@transferwise/components 46.119.5 β 46.120.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/alert/Alert.js +1 -1
- package/build/alert/Alert.js.map +1 -1
- package/build/alert/Alert.mjs +1 -1
- package/build/alert/Alert.mjs.map +1 -1
- package/build/checkbox/Checkbox.js +1 -1
- package/build/checkbox/Checkbox.js.map +1 -1
- package/build/checkbox/Checkbox.mjs +1 -1
- package/build/checkbox/Checkbox.mjs.map +1 -1
- package/build/common/initials.js +17 -7
- package/build/common/initials.js.map +1 -1
- package/build/common/initials.mjs +17 -7
- package/build/common/initials.mjs.map +1 -1
- package/build/field/Field.js +8 -4
- package/build/field/Field.js.map +1 -1
- package/build/field/Field.mjs +8 -4
- package/build/field/Field.mjs.map +1 -1
- package/build/inlineAlert/InlineAlert.js +1 -7
- package/build/inlineAlert/InlineAlert.js.map +1 -1
- package/build/inlineAlert/InlineAlert.mjs +1 -7
- package/build/inlineAlert/InlineAlert.mjs.map +1 -1
- package/build/main.css +20 -1
- package/build/prompt/InlinePrompt/InlinePrompt.js +2 -0
- package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs +2 -0
- package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
- package/build/radioGroup/RadioGroup.js +1 -0
- package/build/radioGroup/RadioGroup.js.map +1 -1
- package/build/radioGroup/RadioGroup.mjs +1 -0
- package/build/radioGroup/RadioGroup.mjs.map +1 -1
- package/build/styles/field/Field.css +10 -1
- package/build/styles/main.css +20 -1
- package/build/styles/prompt/InlinePrompt/InlinePrompt.css +3 -0
- package/build/styles/radioGroup/RadioGroup.css +3 -0
- package/build/styles/typeahead/Typeahead.css +4 -0
- package/build/typeahead/Typeahead.js +20 -7
- package/build/typeahead/Typeahead.js.map +1 -1
- package/build/typeahead/Typeahead.mjs +20 -7
- package/build/typeahead/Typeahead.mjs.map +1 -1
- package/build/types/alert/Alert.d.ts +1 -1
- package/build/types/alert/Alert.d.ts.map +1 -1
- package/build/types/common/initials.d.ts.map +1 -1
- package/build/types/field/Field.d.ts +8 -4
- package/build/types/field/Field.d.ts.map +1 -1
- package/build/types/inlineAlert/InlineAlert.d.ts +1 -7
- package/build/types/inlineAlert/InlineAlert.d.ts.map +1 -1
- package/build/types/listItem/_stories/variants/helpers.d.ts +7 -4
- package/build/types/listItem/_stories/variants/helpers.d.ts.map +1 -1
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +6 -1
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
- package/build/types/radioGroup/RadioGroup.d.ts.map +1 -1
- package/build/types/test-utils/index.d.ts +0 -1
- package/build/types/test-utils/index.d.ts.map +1 -1
- package/build/types/typeahead/Typeahead.d.ts +8 -4
- package/build/types/typeahead/Typeahead.d.ts.map +1 -1
- package/build/types/upload/Upload.d.ts +1 -1
- package/build/types/upload/steps/uploadImageStep/uploadImageStep.d.ts.map +1 -1
- package/build/upload/Upload.js.map +1 -1
- package/build/upload/Upload.mjs.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.js +5 -4
- package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +5 -4
- package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
- package/package.json +9 -8
- package/src/DisabledComponents.story.tsx +1 -3
- package/src/actionButton/ActionButton.story.tsx +42 -45
- package/src/alert/Alert.spec.tsx +1 -1
- package/src/alert/Alert.tsx +2 -2
- package/src/avatar/Avatar.story.tsx +192 -188
- package/src/button/_stories/Button.tests.story.tsx +122 -119
- package/src/carousel/Carousel.story.tsx +4 -7
- package/src/checkbox/Checkbox.story.tsx +42 -21
- package/src/checkbox/Checkbox.tsx +1 -1
- package/src/checkbox/__snapshots__/Checkbox.spec.tsx.snap +1 -1
- package/src/circularButton/CircularButton.story.tsx +10 -2
- package/src/common/bottomSheet/BottomSheet.story.tsx +48 -14
- package/src/common/circle/Circle.story.tsx +62 -55
- package/src/common/initials.spec.tsx +31 -0
- package/src/common/initials.ts +19 -8
- package/src/criticalBanner/CriticalCommsBanner.story.tsx +30 -19
- package/src/dateInput/DateInput.tests.story.tsx +101 -74
- package/src/dateLookup/DateLookup.story.tsx +69 -59
- package/src/field/Field.css +10 -1
- package/src/field/Field.less +13 -2
- package/src/field/Field.spec.tsx +19 -3
- package/src/field/Field.story.tsx +18 -0
- package/src/field/Field.tsx +17 -5
- package/src/header/Header.story.tsx +5 -16
- package/src/header/Header.tests.story.tsx +95 -69
- package/src/info/Info.story.tsx +27 -11
- package/src/inlineAlert/InlineAlert.story.tsx +4 -0
- package/src/inlineAlert/InlineAlert.tsx +1 -7
- package/src/instructionsList/InstructionsList.story.tsx +0 -1
- package/src/listItem/_stories/ListItem.layout.test.story.tsx +1 -3
- package/src/listItem/_stories/variants/ListItem.brightGreen.test.story.tsx +77 -35
- package/src/listItem/_stories/variants/ListItem.dark.test.story.tsx +65 -29
- package/src/listItem/_stories/variants/ListItem.forestGreen.test.story.tsx +77 -35
- package/src/listItem/_stories/variants/ListItem.medium.test.story.tsx +38 -18
- package/src/listItem/_stories/variants/ListItem.neutral.test.story.tsx +0 -1
- package/src/listItem/_stories/variants/ListItem.personal.test.story.tsx +38 -18
- package/src/listItem/_stories/variants/ListItem.rtl.test.story.tsx +77 -29
- package/src/listItem/_stories/variants/ListItem.small.test.story.tsx +65 -18
- package/src/listItem/_stories/variants/helpers.tsx +136 -133
- package/src/main.css +20 -1
- package/src/main.less +1 -0
- package/src/modal/Modal.story.tsx +47 -8
- package/src/moneyInput/MoneyInput.story.tsx +2 -2
- package/src/primitives/PrimitiveAnchor/stories/PrimitiveAnchor.story.tsx +1 -0
- package/src/primitives/PrimitiveAnchor/stories/PrimitiveAnchor.tests.story.tsx +1 -0
- package/src/primitives/PrimitiveButton/stories/PrimitiveButton.story.tsx +1 -0
- package/src/primitives/PrimitiveButton/stories/PrimitiveButton.tests.story.tsx +1 -0
- package/src/prompt/InlinePrompt/InlinePrompt.css +3 -0
- package/src/prompt/InlinePrompt/InlinePrompt.less +5 -1
- package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +17 -0
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +35 -0
- package/src/prompt/InlinePrompt/InlinePrompt.tsx +7 -0
- package/src/provider/theme/ThemeProvider.story.tsx +1 -0
- package/src/radioGroup/RadioGroup.css +3 -0
- package/src/radioGroup/RadioGroup.less +3 -0
- package/src/radioGroup/RadioGroup.story.tsx +2 -0
- package/src/radioGroup/RadioGroup.test.story.tsx +62 -0
- package/src/radioGroup/RadioGroup.tsx +6 -1
- package/src/segmentedControl/SegmentedControl.story.tsx +71 -67
- package/src/snackbar/Snackbar.tests.story.tsx +116 -114
- package/src/statusIcon/StatusIcon.story.tsx +41 -38
- package/src/test-utils/index.tsx +0 -2
- package/src/tokens/tokens.story.tsx +1 -1
- package/src/tooltip/Tooltip.story.tsx +10 -2
- package/src/typeahead/Typeahead.css +4 -0
- package/src/typeahead/Typeahead.less +5 -1
- package/src/typeahead/Typeahead.spec.tsx +1 -1
- package/src/typeahead/Typeahead.story.tsx +151 -3
- package/src/typeahead/Typeahead.tsx +33 -9
- package/src/upload/Upload.story.tsx +1 -1
- package/src/upload/Upload.tests.story.tsx +36 -1
- package/src/upload/Upload.tsx +1 -1
- package/src/upload/steps/uploadImageStep/uploadImageStep.tsx +7 -3
- package/src/withId/withId.story.tsx +1 -1
- package/build/types/test-utils/story-config.d.ts +0 -64
- package/build/types/test-utils/story-config.d.ts.map +0 -1
- package/src/test-utils/story-config.ts +0 -95
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { Args } from '@storybook/react-webpack5';
|
|
2
2
|
import { Illustration } from '@wise/art';
|
|
3
|
-
import React from 'react';
|
|
4
3
|
|
|
5
4
|
import Display from '../display';
|
|
6
5
|
|
|
@@ -54,11 +53,9 @@ const carouselCards: CarouselCard[] = [
|
|
|
54
53
|
},
|
|
55
54
|
];
|
|
56
55
|
|
|
57
|
-
const Template: StoryFn = (args) => {
|
|
58
|
-
return <Carousel header="Pretty nifty stuff" cards={carouselCards} {...args} />;
|
|
59
|
-
};
|
|
60
|
-
|
|
61
56
|
export const CarouselDefault = {
|
|
62
|
-
render:
|
|
57
|
+
render: (args: Args) => {
|
|
58
|
+
return <Carousel header="Pretty nifty stuff" cards={carouselCards} {...args} />;
|
|
59
|
+
},
|
|
63
60
|
args: {},
|
|
64
61
|
};
|
|
@@ -2,9 +2,10 @@ import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
|
2
2
|
import { fn } from 'storybook/test';
|
|
3
3
|
|
|
4
4
|
import { Field } from '../field/Field';
|
|
5
|
-
import { lorem10
|
|
5
|
+
import { lorem10 } from '../test-utils';
|
|
6
6
|
|
|
7
7
|
import Checkbox from './Checkbox';
|
|
8
|
+
import { allModes } from '../../.storybook/modes';
|
|
8
9
|
|
|
9
10
|
const meta: Meta<typeof Checkbox> = {
|
|
10
11
|
component: Checkbox,
|
|
@@ -20,33 +21,53 @@ type Story = StoryObj<typeof Checkbox>;
|
|
|
20
21
|
|
|
21
22
|
export const Basic: Story = {};
|
|
22
23
|
|
|
23
|
-
export const Multiple: Story =
|
|
24
|
-
{
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
export const Multiple: Story = {
|
|
25
|
+
render: (args) => {
|
|
26
|
+
return (
|
|
27
|
+
<>
|
|
28
|
+
<Checkbox {...args} />
|
|
29
|
+
<Checkbox {...args} checked />
|
|
30
|
+
<Checkbox {...args} label={lorem10} />
|
|
31
|
+
<Checkbox {...args} label={lorem10} secondary={lorem10} />
|
|
32
|
+
<Checkbox {...args} disabled />
|
|
33
|
+
</>
|
|
34
|
+
);
|
|
35
|
+
},
|
|
36
|
+
parameters: {
|
|
37
|
+
variants: ['default', 'dark', 'rtl'],
|
|
38
|
+
chromatic: {
|
|
39
|
+
dark: allModes.dark,
|
|
40
|
+
rtl: allModes.rtl,
|
|
35
41
|
},
|
|
36
42
|
},
|
|
37
|
-
|
|
38
|
-
);
|
|
43
|
+
};
|
|
39
44
|
|
|
40
|
-
export const MultipleMobile: Story =
|
|
41
|
-
|
|
42
|
-
|
|
45
|
+
export const MultipleMobile: Story = {
|
|
46
|
+
...Multiple,
|
|
47
|
+
parameters: {
|
|
48
|
+
variants: ['default', 'dark', 'rtl', 'mobile'],
|
|
49
|
+
chromatic: {
|
|
50
|
+
dark: allModes.dark,
|
|
51
|
+
rtl: allModes.rtl,
|
|
52
|
+
mobile: allModes.largeMobile,
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
};
|
|
43
56
|
|
|
44
57
|
export const WithinField = {
|
|
45
58
|
decorators: [
|
|
46
59
|
(Story) => (
|
|
47
|
-
|
|
48
|
-
<
|
|
49
|
-
|
|
60
|
+
<>
|
|
61
|
+
<Field label="Field label">
|
|
62
|
+
<Story />
|
|
63
|
+
</Field>
|
|
64
|
+
<Field label="Field label" message="Something went wrong" sentiment="negative">
|
|
65
|
+
<Story />
|
|
66
|
+
</Field>
|
|
67
|
+
<Field label="Field label" message="Something went great" sentiment="positive">
|
|
68
|
+
<Story />
|
|
69
|
+
</Field>
|
|
70
|
+
</>
|
|
50
71
|
),
|
|
51
72
|
],
|
|
52
73
|
} satisfies Story;
|
|
@@ -44,7 +44,7 @@ export default function Checkbox({
|
|
|
44
44
|
const innerDisabled = disabled || readOnly;
|
|
45
45
|
return (
|
|
46
46
|
<div id={id} className={classList}>
|
|
47
|
-
<label className={clsx({ disabled })}>
|
|
47
|
+
<label className={clsx('np-checkbox-label', { disabled })}>
|
|
48
48
|
<CheckboxButton
|
|
49
49
|
className="p-r-2"
|
|
50
50
|
checked={checked}
|
|
@@ -4,9 +4,9 @@ import { ControlType, Priority } from '../common';
|
|
|
4
4
|
|
|
5
5
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
6
6
|
import CircularButton from './CircularButton';
|
|
7
|
-
import { storyConfig } from '../test-utils';
|
|
8
7
|
import Title from '../title';
|
|
9
8
|
import Body from '../body';
|
|
9
|
+
import { allModes } from '../../.storybook/modes';
|
|
10
10
|
|
|
11
11
|
export default {
|
|
12
12
|
component: CircularButton,
|
|
@@ -87,4 +87,12 @@ export const All: Story = {
|
|
|
87
87
|
},
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
-
export const All400Zoom: Story =
|
|
90
|
+
export const All400Zoom: Story = {
|
|
91
|
+
...All,
|
|
92
|
+
parameters: {
|
|
93
|
+
variants: ['400%'],
|
|
94
|
+
chromatic: {
|
|
95
|
+
'400%': allModes.zoom400,
|
|
96
|
+
},
|
|
97
|
+
},
|
|
98
|
+
};
|
|
@@ -6,11 +6,12 @@ import { useState } from 'react';
|
|
|
6
6
|
import Body from '../../body/Body';
|
|
7
7
|
import Button from '../../button';
|
|
8
8
|
import NavigationOption from '../../navigationOption';
|
|
9
|
-
import { lorem10, lorem500
|
|
9
|
+
import { lorem10, lorem500 } from '../../test-utils';
|
|
10
10
|
import Title from '../../title/Title';
|
|
11
11
|
import { Typography } from '../propsValues/typography';
|
|
12
12
|
|
|
13
13
|
import BottomSheet from './BottomSheet';
|
|
14
|
+
import { allModes } from '../../../.storybook/modes';
|
|
14
15
|
|
|
15
16
|
export default {
|
|
16
17
|
component: BottomSheet,
|
|
@@ -64,7 +65,15 @@ export const Basic: Story = {
|
|
|
64
65
|
},
|
|
65
66
|
};
|
|
66
67
|
|
|
67
|
-
export const BasicMobile: Story =
|
|
68
|
+
export const BasicMobile: Story = {
|
|
69
|
+
...Basic,
|
|
70
|
+
parameters: {
|
|
71
|
+
variants: ['mobile'],
|
|
72
|
+
chromatic: {
|
|
73
|
+
mobile: allModes.largeMobile,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
};
|
|
68
77
|
|
|
69
78
|
export const WithOverflowContent: Story = {
|
|
70
79
|
args: {
|
|
@@ -95,18 +104,43 @@ export const WithOverflowContent: Story = {
|
|
|
95
104
|
},
|
|
96
105
|
};
|
|
97
106
|
|
|
98
|
-
export const WithOverflowContentMobile: Story =
|
|
99
|
-
|
|
100
|
-
|
|
107
|
+
export const WithOverflowContentMobile: Story = {
|
|
108
|
+
...WithOverflowContent,
|
|
109
|
+
parameters: {
|
|
110
|
+
variants: ['mobile'],
|
|
111
|
+
chromatic: {
|
|
112
|
+
mobile: allModes.largeMobile,
|
|
113
|
+
},
|
|
114
|
+
},
|
|
115
|
+
};
|
|
101
116
|
|
|
102
|
-
export const WithOverflowContentDark: Story =
|
|
103
|
-
|
|
104
|
-
|
|
117
|
+
export const WithOverflowContentDark: Story = {
|
|
118
|
+
...WithOverflowContent,
|
|
119
|
+
parameters: {
|
|
120
|
+
variants: ['dark'],
|
|
121
|
+
chromatic: {
|
|
122
|
+
dark: allModes.dark,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
};
|
|
105
126
|
|
|
106
|
-
export const WithOverflowContentDarkMobile: Story =
|
|
107
|
-
|
|
108
|
-
|
|
127
|
+
export const WithOverflowContentDarkMobile: Story = {
|
|
128
|
+
...WithOverflowContent,
|
|
129
|
+
parameters: {
|
|
130
|
+
variants: ['dark', 'mobile'],
|
|
131
|
+
chromatic: {
|
|
132
|
+
dark: allModes.dark,
|
|
133
|
+
mobile: allModes.largeMobile,
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
};
|
|
109
137
|
|
|
110
|
-
export const WithOverflowContentZoom400: Story =
|
|
111
|
-
|
|
112
|
-
|
|
138
|
+
export const WithOverflowContentZoom400: Story = {
|
|
139
|
+
...WithOverflowContent,
|
|
140
|
+
parameters: {
|
|
141
|
+
variants: ['400%'],
|
|
142
|
+
chromatic: {
|
|
143
|
+
'400%': allModes.zoom400,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
|
-
import { storyConfig } from '../../test-utils';
|
|
3
2
|
import Circle from './Circle';
|
|
4
3
|
import { Profile } from '@transferwise/icons';
|
|
5
|
-
import { action } from 'storybook/actions';
|
|
6
4
|
import { CircleProps } from '.';
|
|
7
5
|
import Body from '../../body';
|
|
6
|
+
import { allModes } from '../../../.storybook/modes';
|
|
8
7
|
|
|
9
8
|
export default {
|
|
10
9
|
title: 'Internal/Circle',
|
|
11
10
|
component: Circle,
|
|
11
|
+
tags: ['!manifest'],
|
|
12
12
|
} satisfies Meta<typeof Circle>;
|
|
13
13
|
|
|
14
14
|
type Story = StoryObj<typeof Circle>;
|
|
@@ -25,61 +25,68 @@ export const Basic: Story = {
|
|
|
25
25
|
},
|
|
26
26
|
};
|
|
27
27
|
|
|
28
|
-
export const Sizes: Story =
|
|
29
|
-
{
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
{
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
28
|
+
export const Sizes: Story = {
|
|
29
|
+
render: () => {
|
|
30
|
+
const content = <Profile size={16} />;
|
|
31
|
+
const sizes: CircleProps['size'][] = [16, 24, 32, 40, 48, 56, 72];
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
style={{
|
|
35
|
+
gap: '1em',
|
|
36
|
+
display: 'grid',
|
|
37
|
+
justifyContent: 'space-between',
|
|
38
|
+
gridTemplate: `auto auto / repeat(${sizes.length}, min-content)`,
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
{sizes.map((size) => (
|
|
42
|
+
<Circle key={size} size={size} className="bg-neutral">
|
|
43
|
+
{content}
|
|
44
|
+
</Circle>
|
|
45
|
+
))}
|
|
46
|
+
</div>
|
|
47
|
+
);
|
|
48
|
+
},
|
|
49
|
+
parameters: {
|
|
50
|
+
variants: ['light', 'dark'],
|
|
51
|
+
chromatic: {
|
|
52
|
+
light: allModes.light,
|
|
53
|
+
dark: allModes.dark,
|
|
49
54
|
},
|
|
50
55
|
},
|
|
51
|
-
|
|
52
|
-
);
|
|
56
|
+
};
|
|
53
57
|
|
|
54
|
-
export const FixedSize: Story =
|
|
55
|
-
{
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
>
|
|
68
|
-
<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
58
|
+
export const FixedSize: Story = {
|
|
59
|
+
render: () => {
|
|
60
|
+
const size = 72;
|
|
61
|
+
const content = <Profile size={16} />;
|
|
62
|
+
return (
|
|
63
|
+
<div
|
|
64
|
+
style={{
|
|
65
|
+
gap: '1em',
|
|
66
|
+
display: 'grid',
|
|
67
|
+
justifyContent: 'space-between',
|
|
68
|
+
gridTemplate: 'auto auto / repeat(2, 180px)',
|
|
69
|
+
}}
|
|
70
|
+
>
|
|
71
|
+
<Body className="d-block">
|
|
72
|
+
Dynamic Size (<code>--size-{size}</code>)
|
|
73
|
+
</Body>
|
|
74
|
+
<Body className="d-block">
|
|
75
|
+
Fixed Size (<code>{size}px</code>)
|
|
76
|
+
</Body>
|
|
77
|
+
<Circle size={72} fixedSize={false} className="bg-neutral">
|
|
78
|
+
{content}
|
|
79
|
+
</Circle>
|
|
80
|
+
<Circle size={72} fixedSize className="bg-neutral">
|
|
81
|
+
{content}
|
|
82
|
+
</Circle>
|
|
83
|
+
</div>
|
|
84
|
+
);
|
|
85
|
+
},
|
|
86
|
+
parameters: {
|
|
87
|
+
variants: ['400%'],
|
|
88
|
+
chromatic: {
|
|
89
|
+
zoom400: allModes.zoom400,
|
|
82
90
|
},
|
|
83
91
|
},
|
|
84
|
-
|
|
85
|
-
);
|
|
92
|
+
};
|
|
@@ -52,4 +52,35 @@ describe('getInitials', () => {
|
|
|
52
52
|
expect(getInitials('(Super) Fantastic Squirrel')).toBe('FS');
|
|
53
53
|
expect(getInitials('Super (Fantastic) Squirrel')).toBe('SS');
|
|
54
54
|
});
|
|
55
|
+
|
|
56
|
+
it('handles emojis correctly', () => {
|
|
57
|
+
expect(getInitials('π')).toBe('π');
|
|
58
|
+
expect(getInitials('π Christian Dalby')).toBe('πD');
|
|
59
|
+
expect(getInitials('Christian π')).toBe('Cπ');
|
|
60
|
+
expect(getInitials('π Christian π')).toBe('ππ');
|
|
61
|
+
expect(getInitials('π Party π Time')).toBe('πT');
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
it('handles unicode strings correctly', () => {
|
|
65
|
+
expect(getInitials('\u{1F600}')).toBe('\u{1F600}');
|
|
66
|
+
expect(getInitials('\u{1F600} Christian Dalby')).toBe('\u{1F600}D');
|
|
67
|
+
expect(getInitials('Christian \u{1F600}')).toBe('C\u{1F600}');
|
|
68
|
+
expect(getInitials('\u{1F60E} Christian \u{1F60E}')).toBe('\u{1F60E}\u{1F60E}');
|
|
69
|
+
expect(getInitials('\u{1F389} Party \u{1F38A} Time')).toBe('\u{1F389}T');
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('handles multi-byte emojis with skin tones and ZWJ sequences', () => {
|
|
73
|
+
expect(getInitials('π¨βπ©βπ§βπ¦')).toBe('π¨βπ©βπ§βπ¦');
|
|
74
|
+
expect(getInitials('π¨βπ©βπ§βπ¦ Family')).toBe('π¨βπ©βπ§βπ¦F');
|
|
75
|
+
expect(getInitials('ππ½')).toBe('ππ½');
|
|
76
|
+
expect(getInitials('Christian ππ½')).toBe('Cππ½');
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
it('handles diacritical marks correctly', () => {
|
|
80
|
+
expect(getInitials('AndrΓ© MΓΌller')).toBe('AM');
|
|
81
|
+
expect(getInitials('Γngel MuΓ±oz')).toBe('ΓM');
|
|
82
|
+
expect(getInitials('FranΓ§ois Γlis')).toBe('FΓ');
|
|
83
|
+
expect(getInitials('Εukasz Εlusarczyk')).toBe('ΕΕ');
|
|
84
|
+
expect(getInitials('Γmer Γzdemir')).toBe('ΓΓ');
|
|
85
|
+
});
|
|
55
86
|
});
|
package/src/common/initials.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
function startsWithParenthesis(part: string) {
|
|
2
|
+
return /^[({[<]/.test(part);
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
// Reuse a single Intl.Segmenter instance to avoid repeated allocations
|
|
6
|
+
const GRAPHEME_SEGMENTER = new Intl.Segmenter('en', { granularity: 'grapheme' });
|
|
7
|
+
|
|
8
|
+
// Helper to split the string into grapheme clusters, which handles complex characters correctly
|
|
9
|
+
function getGraphemes(str: string): string[] {
|
|
10
|
+
return Array.from(GRAPHEME_SEGMENTER.segment(str), (s) => s.segment);
|
|
11
|
+
}
|
|
12
|
+
|
|
1
13
|
export function getInitials(name: string) {
|
|
2
14
|
if (name.length === 2 && /^[A-Z]{2}$/.test(name)) {
|
|
3
15
|
return name;
|
|
@@ -6,17 +18,16 @@ export function getInitials(name: string) {
|
|
|
6
18
|
const allInitials = name
|
|
7
19
|
.split(' ')
|
|
8
20
|
.filter((part) => !startsWithParenthesis(part))
|
|
9
|
-
.map((part) => part[0])
|
|
21
|
+
.map((part) => getGraphemes(part)[0])
|
|
10
22
|
.join('')
|
|
11
23
|
.toUpperCase();
|
|
12
24
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
return allInitials[0] + allInitials.slice(-1);
|
|
25
|
+
// Get graphemes of the initials string to handle complex characters correctly
|
|
26
|
+
const graphemes = getGraphemes(allInitials);
|
|
18
27
|
|
|
19
|
-
|
|
20
|
-
return
|
|
28
|
+
if (graphemes.length === 1) {
|
|
29
|
+
return graphemes[0];
|
|
21
30
|
}
|
|
31
|
+
|
|
32
|
+
return graphemes[0] + graphemes[graphemes.length - 1];
|
|
22
33
|
}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
import { Meta } from '@storybook/react-webpack5';
|
|
1
|
+
import { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
2
2
|
|
|
3
3
|
import CriticalCommsBanner from '.';
|
|
4
|
-
import {
|
|
4
|
+
import { allModes } from '../../.storybook/modes';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
7
|
component: CriticalCommsBanner,
|
|
8
8
|
title: 'Prompts/CriticalCommsBanner',
|
|
9
9
|
} satisfies Meta<typeof CriticalCommsBanner>;
|
|
10
10
|
|
|
11
|
+
type Story = StoryObj<typeof CriticalCommsBanner>;
|
|
12
|
+
|
|
11
13
|
export const Basic = {
|
|
12
14
|
args: {
|
|
13
15
|
title: 'Your account is overdrawn',
|
|
@@ -16,25 +18,34 @@ export const Basic = {
|
|
|
16
18
|
},
|
|
17
19
|
};
|
|
18
20
|
|
|
19
|
-
export const Variants =
|
|
20
|
-
{
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
export const Variants: Story = {
|
|
22
|
+
args: {
|
|
23
|
+
title: 'Your account is overdrawn',
|
|
24
|
+
subtitle: 'Add money within the next 30 days',
|
|
25
|
+
action: { label: 'Take action', href: 'https://wise.com' },
|
|
26
|
+
},
|
|
27
|
+
parameters: {
|
|
28
|
+
variants: ['default', 'dark', 'rtl'],
|
|
29
|
+
chromatic: {
|
|
30
|
+
dark: allModes.dark,
|
|
31
|
+
rtl: allModes.rtl,
|
|
25
32
|
},
|
|
26
33
|
},
|
|
27
|
-
|
|
28
|
-
);
|
|
34
|
+
};
|
|
29
35
|
|
|
30
|
-
export const Mobile =
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
export const Mobile: Story = {
|
|
37
|
+
tags: ['!autodocs'],
|
|
38
|
+
args: {
|
|
39
|
+
title: 'Your account is overdrawn',
|
|
40
|
+
subtitle: 'Add money within the next 30 days',
|
|
41
|
+
action: { label: 'Take action', href: 'https://wise.com' },
|
|
42
|
+
},
|
|
43
|
+
parameters: {
|
|
44
|
+
variants: ['default', 'dark', 'rtl', 'mobile'],
|
|
45
|
+
chromatic: {
|
|
46
|
+
dark: allModes.dark,
|
|
47
|
+
rtl: allModes.rtl,
|
|
48
|
+
mobile: allModes.largeMobile,
|
|
37
49
|
},
|
|
38
50
|
},
|
|
39
|
-
|
|
40
|
-
);
|
|
51
|
+
};
|