@transferwise/components 46.117.1 → 46.119.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/dateLookup/dayCalendar/DayCalendar.js +4 -4
- package/build/dateLookup/dayCalendar/DayCalendar.js.map +1 -1
- package/build/dateLookup/dayCalendar/table/DayCalendarTable.js +4 -4
- package/build/dateLookup/dayCalendar/table/DayCalendarTable.js.map +1 -1
- package/build/dateLookup/monthCalendar/MonthCalendar.js +4 -4
- package/build/dateLookup/monthCalendar/MonthCalendar.js.map +1 -1
- package/build/dateLookup/yearCalendar/YearCalendar.js +4 -4
- package/build/dateLookup/yearCalendar/YearCalendar.js.map +1 -1
- package/build/dimmer/Dimmer.js +4 -4
- package/build/dimmer/Dimmer.js.map +1 -1
- package/build/index.js +4 -0
- package/build/index.js.map +1 -1
- package/build/index.mjs +2 -0
- package/build/index.mjs.map +1 -1
- package/build/inputs/SelectInput.js +4 -4
- package/build/inputs/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput.mjs +4 -4
- package/build/inputs/SelectInput.mjs.map +1 -1
- package/build/listItem/Prompt/ListItemPrompt.js +2 -0
- package/build/listItem/Prompt/ListItemPrompt.js.map +1 -1
- package/build/listItem/Prompt/ListItemPrompt.mjs +2 -0
- package/build/listItem/Prompt/ListItemPrompt.mjs.map +1 -1
- package/build/moneyInput/MoneyInput.js +2 -2
- package/build/moneyInput/MoneyInput.js.map +1 -1
- package/build/moneyInput/MoneyInput.mjs +2 -2
- package/build/moneyInput/MoneyInput.mjs.map +1 -1
- package/build/promoCard/PromoCard.js +3 -3
- package/build/promoCard/PromoCard.js.map +1 -1
- package/build/promoCard/PromoCardGroup.js +2 -2
- package/build/promoCard/PromoCardGroup.js.map +1 -1
- package/build/promoCard/PromoCardGroup.mjs +2 -2
- package/build/promoCard/PromoCardGroup.mjs.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.js +8 -3
- package/build/prompt/InlinePrompt/InlinePrompt.js.map +1 -1
- package/build/prompt/InlinePrompt/InlinePrompt.mjs +8 -3
- package/build/prompt/InlinePrompt/InlinePrompt.mjs.map +1 -1
- package/build/typeahead/Typeahead.js +2 -2
- package/build/typeahead/Typeahead.js.map +1 -1
- package/build/typeahead/Typeahead.mjs +2 -2
- package/build/typeahead/Typeahead.mjs.map +1 -1
- package/build/types/index.d.ts +4 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/listItem/ListItem.d.ts +1 -1
- package/build/types/listItem/Prompt/ListItemPrompt.d.ts +2 -2
- package/build/types/listItem/Prompt/ListItemPrompt.d.ts.map +1 -1
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts +9 -2
- package/build/types/prompt/InlinePrompt/InlinePrompt.d.ts.map +1 -1
- package/build/upload/Upload.js +2 -2
- package/build/upload/Upload.js.map +1 -1
- package/build/upload/Upload.mjs +2 -2
- package/build/upload/Upload.mjs.map +1 -1
- package/package.json +37 -37
- package/src/accordion/AccordionItem/__snapshots__/AccordionItem.spec.js.snap +1 -1
- package/src/accordion/__snapshots__/Accordion.spec.js.snap +1 -1
- package/src/actionButton/__snapshots__/ActionButton.spec.tsx.snap +1 -1
- package/src/alert/Alert.story.tsx +1 -1
- package/src/alert/Alert.tests.story.tsx +1 -1
- package/src/avatarWrapper/__snapshots__/AvatarWrapper.spec.tsx.snap +1 -1
- package/src/button/Button.vars.less +28 -7
- package/src/checkbox/__snapshots__/Checkbox.spec.tsx.snap +1 -1
- package/src/chevron/__snapshots__/Chevron.spec.tsx.snap +1 -1
- package/src/chips/__snapshots__/Chips.spec.tsx.snap +1 -1
- package/src/common/RadioButton/__snapshots__/RadioButton.spec.tsx.snap +1 -1
- package/src/common/bottomSheet/__snapshots__/BottomSheet.spec.tsx.snap +1 -1
- package/src/common/card/__snapshots__/Card.spec.tsx.snap +1 -1
- package/src/common/closeButton/__snapshots__/CloseButton.spec.tsx.snap +1 -1
- package/src/common/flowHeader/__snapshots__/FlowHeader.spec.tsx.snap +1 -1
- package/src/common/panel/__snapshots__/Panel.spec.tsx.snap +1 -1
- package/src/criticalBanner/CriticalCommsBanner.story.tsx +1 -1
- package/src/flowNavigation/__snapshots__/FlowNavigation.spec.js.snap +1 -1
- package/src/iconButton/IconButton.story.tsx +2 -2
- package/src/index.ts +4 -0
- package/src/inlineAlert/InlineAlert.story.tsx +1 -1
- package/src/inputs/SelectInput.tsx +21 -19
- package/src/link/Link.story.tsx +2 -2
- package/src/listItem/Prompt/ListItemPrompt.spec.tsx +48 -0
- package/src/listItem/Prompt/ListItemPrompt.story.tsx +1 -0
- package/src/listItem/Prompt/ListItemPrompt.tsx +7 -2
- package/src/logo/__snapshots__/Logo.spec.tsx.snap +1 -1
- package/src/nudge/Nudge.story.tsx +1 -1
- package/src/overlayHeader/__snapshots__/OverlayHeader.spec.tsx.snap +1 -1
- package/src/popover/__snapshots__/Popover.spec.tsx.snap +1 -1
- package/src/promoCard/__snapshots__/PromoCard.spec.tsx.snap +1 -1
- package/src/promoCard/__snapshots__/PromoCardGroup.spec.tsx.snap +1 -1
- package/src/prompt/InlinePrompt/InlinePrompt.spec.tsx +29 -1
- package/src/prompt/InlinePrompt/InlinePrompt.story.tsx +45 -4
- package/src/prompt/InlinePrompt/InlinePrompt.tsx +12 -4
- package/src/provider/theme/ThemeProvider.story.tsx +1 -1
- package/src/sentimentSurface/SentimentSurface.story.tsx +163 -102
- package/src/sentimentSurface/SentimentSurface.tests.story.tsx +6 -2
- package/src/tile/__snapshots__/Tile.spec.tsx.snap +1 -1
- package/src/{neptune-css/NeptuneCSS.story.tsx → tokens/tokens.story.tsx} +2 -2
- package/src/tooltip/__snapshots__/Tooltip.spec.tsx.snap +1 -1
- package/src/withId/withId.story.tsx +1 -0
package/src/index.ts
CHANGED
|
@@ -35,6 +35,7 @@ export type { HeaderProps } from './header';
|
|
|
35
35
|
export type { EmphasisProps } from './emphasis';
|
|
36
36
|
export type { FieldProps } from './field/Field';
|
|
37
37
|
export type { InfoProps } from './info';
|
|
38
|
+
export type { InlinePromptProps } from './prompt';
|
|
38
39
|
export type { InputWithDisplayFormatProps } from './inputWithDisplayFormat';
|
|
39
40
|
export type { InputProps } from './inputs/Input';
|
|
40
41
|
export type { InputGroupProps } from './inputs/InputGroup';
|
|
@@ -89,6 +90,7 @@ export type { SnackbarContextType } from './snackbar/SnackbarContext';
|
|
|
89
90
|
export type { StatusIconProps } from './statusIcon';
|
|
90
91
|
export type { StickyProps } from './sticky';
|
|
91
92
|
export type { SummaryProps } from './summary';
|
|
93
|
+
export type { SentimentSurfaceProps } from './sentimentSurface';
|
|
92
94
|
export type { SwitchProps } from './switch';
|
|
93
95
|
export type { SwitchOptionProps } from './switchOption';
|
|
94
96
|
export type { TabItem, TabsProps } from './tabs';
|
|
@@ -169,6 +171,7 @@ export { default as Header } from './header';
|
|
|
169
171
|
export { default as Image } from './image';
|
|
170
172
|
export { default as Info } from './info';
|
|
171
173
|
export { default as InlineAlert } from './inlineAlert';
|
|
174
|
+
export { InlinePrompt } from './prompt';
|
|
172
175
|
export { default as InputWithDisplayFormat } from './inputWithDisplayFormat';
|
|
173
176
|
export { Input } from './inputs/Input';
|
|
174
177
|
export { InputGroup } from './inputs/InputGroup';
|
|
@@ -209,6 +212,7 @@ export { default as ResponsivePanel } from './common/responsivePanel';
|
|
|
209
212
|
export { default as Section } from './section';
|
|
210
213
|
export { default as SegmentedControl } from './segmentedControl';
|
|
211
214
|
export { default as Select } from './select';
|
|
215
|
+
export { default as SentimentSurface } from './sentimentSurface';
|
|
212
216
|
export { default as SlidingPanel } from './slidingPanel';
|
|
213
217
|
export { default as SnackbarPortal } from './snackbar/Snackbar';
|
|
214
218
|
export { SnackbarConsumer, SnackbarContext } from './snackbar/SnackbarContext';
|
|
@@ -250,8 +250,10 @@ const defaultRenderTrigger = (({ content, placeholderShown, clear, disabled, siz
|
|
|
250
250
|
</InputGroup>
|
|
251
251
|
)) satisfies SelectInputProps['renderTrigger'];
|
|
252
252
|
|
|
253
|
-
interface SelectInputClearButtonProps
|
|
254
|
-
|
|
253
|
+
interface SelectInputClearButtonProps extends Pick<
|
|
254
|
+
React.ComponentPropsWithoutRef<'button'>,
|
|
255
|
+
'className' | 'onClick'
|
|
256
|
+
> {}
|
|
255
257
|
|
|
256
258
|
function SelectInputClearButton({ className, onClick }: SelectInputClearButtonProps) {
|
|
257
259
|
const intl = useIntl();
|
|
@@ -576,17 +578,10 @@ const SelectInputOptionsContainer = forwardRef(function SelectInputOptionsContai
|
|
|
576
578
|
);
|
|
577
579
|
});
|
|
578
580
|
|
|
579
|
-
interface SelectInputOptionsProps<T = string>
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
| 'renderValue'
|
|
584
|
-
| 'renderFooter'
|
|
585
|
-
| 'filterable'
|
|
586
|
-
| 'filterPlaceholder'
|
|
587
|
-
| 'id'
|
|
588
|
-
| 'parentId'
|
|
589
|
-
> {
|
|
581
|
+
interface SelectInputOptionsProps<T = string> extends Pick<
|
|
582
|
+
SelectInputProps<T>,
|
|
583
|
+
'items' | 'renderValue' | 'renderFooter' | 'filterable' | 'filterPlaceholder' | 'id' | 'parentId'
|
|
584
|
+
> {
|
|
590
585
|
searchInputRef: React.MutableRefObject<HTMLInputElement | null>;
|
|
591
586
|
listboxRef: React.MutableRefObject<HTMLDivElement | null>;
|
|
592
587
|
filterQuery: string;
|
|
@@ -828,14 +823,19 @@ function SelectInputOptions<T = string>({
|
|
|
828
823
|
<Virtualizer
|
|
829
824
|
ref={virtualiserHandlerRef}
|
|
830
825
|
key={needle}
|
|
831
|
-
|
|
826
|
+
data={filteredItems}
|
|
832
827
|
keepMounted={mountedIndexes}
|
|
833
828
|
scrollRef={listboxRef} // `VList` doesn't expose this
|
|
834
829
|
onScroll={async () => {
|
|
835
830
|
if (!virtualiserHandlerRef.current) return;
|
|
836
831
|
|
|
837
|
-
const startIndex = virtualiserHandlerRef.current.
|
|
838
|
-
|
|
832
|
+
const startIndex = virtualiserHandlerRef.current.findItemIndex(
|
|
833
|
+
virtualiserHandlerRef.current.scrollOffset,
|
|
834
|
+
);
|
|
835
|
+
const endIndex = virtualiserHandlerRef.current.findItemIndex(
|
|
836
|
+
virtualiserHandlerRef.current.scrollOffset +
|
|
837
|
+
virtualiserHandlerRef.current.viewportSize,
|
|
838
|
+
);
|
|
839
839
|
|
|
840
840
|
setMountedIndexes((prevMountedIndexes) => {
|
|
841
841
|
const indexes = new Set(prevMountedIndexes);
|
|
@@ -848,7 +848,7 @@ function SelectInputOptions<T = string>({
|
|
|
848
848
|
});
|
|
849
849
|
}}
|
|
850
850
|
>
|
|
851
|
-
{(index) => (
|
|
851
|
+
{(item, index) => (
|
|
852
852
|
// The position of each item can't be inferred by browsers when
|
|
853
853
|
// virtualizing, as some of the items may not be in the DOM
|
|
854
854
|
<SelectInputItemsCountContext.Provider value={filteredItems.length}>
|
|
@@ -924,8 +924,10 @@ function SelectInputItemView<T = string>({
|
|
|
924
924
|
return null;
|
|
925
925
|
}
|
|
926
926
|
|
|
927
|
-
interface SelectInputGroupItemViewProps<T = string>
|
|
928
|
-
|
|
927
|
+
interface SelectInputGroupItemViewProps<T = string> extends SelectInputItemViewProps<
|
|
928
|
+
T,
|
|
929
|
+
SelectInputGroupItem<T | undefined>
|
|
930
|
+
> {}
|
|
929
931
|
|
|
930
932
|
function SelectInputGroupItemView<T = string>({
|
|
931
933
|
item,
|
package/src/link/Link.story.tsx
CHANGED
|
@@ -161,8 +161,8 @@ export const Basic = () => {
|
|
|
161
161
|
};
|
|
162
162
|
|
|
163
163
|
/**
|
|
164
|
-
* `Link` is sentiment-aware and will automatically adjust its
|
|
165
|
-
*
|
|
164
|
+
* `Link` is sentiment-aware and will automatically adjust its colours if wrapped inside
|
|
165
|
+
* the [SentimentSurface](?path=/docs/foundations-sentimentsurface--docs) component
|
|
166
166
|
*/
|
|
167
167
|
export const SentimentAwareness = function Render() {
|
|
168
168
|
return (['success', 'warning', 'negative'] as const).map((sentiment) => (
|
|
@@ -69,4 +69,52 @@ describe('ListItem.Prompt', () => {
|
|
|
69
69
|
expect(screen.getByTestId('InlinePrompt_Muted')).toBeInTheDocument();
|
|
70
70
|
});
|
|
71
71
|
});
|
|
72
|
+
|
|
73
|
+
[
|
|
74
|
+
{ sentiment: Sentiment.NEGATIVE as const, iconLabel: 'Error:' },
|
|
75
|
+
{ sentiment: Sentiment.WARNING as const, iconLabel: 'Warning:' },
|
|
76
|
+
{ sentiment: Sentiment.NEUTRAL as const, iconLabel: 'Information:' },
|
|
77
|
+
{ sentiment: Sentiment.POSITIVE as const, iconLabel: 'Success:' },
|
|
78
|
+
{ sentiment: 'proposition' as const, iconLabel: '' },
|
|
79
|
+
].forEach(({ sentiment, iconLabel }) => {
|
|
80
|
+
describe(sentiment, () => {
|
|
81
|
+
const customLabel = 'Custom icon label';
|
|
82
|
+
|
|
83
|
+
if (!iconLabel) {
|
|
84
|
+
it('should not have accessible name for the icon', () => {
|
|
85
|
+
const { container } = render(
|
|
86
|
+
<ListItem
|
|
87
|
+
title="Test Title"
|
|
88
|
+
prompt={<ListItem.Prompt sentiment={sentiment}>Message</ListItem.Prompt>}
|
|
89
|
+
/>,
|
|
90
|
+
);
|
|
91
|
+
expect(container.querySelector('svg')).not.toHaveAccessibleName();
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
it('should use default aria label', () => {
|
|
95
|
+
render(
|
|
96
|
+
<ListItem
|
|
97
|
+
title="Test Title"
|
|
98
|
+
prompt={<ListItem.Prompt sentiment={sentiment}>Message</ListItem.Prompt>}
|
|
99
|
+
/>,
|
|
100
|
+
);
|
|
101
|
+
expect(screen.getByLabelText(iconLabel)).toBeInTheDocument();
|
|
102
|
+
});
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
it('should allow for customisation of aria label', () => {
|
|
106
|
+
render(
|
|
107
|
+
<ListItem
|
|
108
|
+
title="Test Title"
|
|
109
|
+
prompt={
|
|
110
|
+
<ListItem.Prompt sentiment={sentiment} iconLabel={customLabel}>
|
|
111
|
+
Message
|
|
112
|
+
</ListItem.Prompt>
|
|
113
|
+
}
|
|
114
|
+
/>,
|
|
115
|
+
);
|
|
116
|
+
expect(screen.getByLabelText(customLabel)).toBeInTheDocument();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
72
120
|
});
|
|
@@ -4,7 +4,7 @@ import { Sentiment } from '../../common';
|
|
|
4
4
|
import { ListItemContext, type ListItemContextData } from '../ListItemContext';
|
|
5
5
|
import { InlinePrompt, type InlinePromptProps } from '../../prompt';
|
|
6
6
|
|
|
7
|
-
export type ListItemPromptProps = Pick<InlinePromptProps, 'children' | 'sentiment' | '
|
|
7
|
+
export type ListItemPromptProps = Pick<InlinePromptProps, 'children' | 'sentiment' | 'iconLabel'>;
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
10
|
* This component allows for rendering an Inline Prompt. <br />
|
|
@@ -12,7 +12,11 @@ export type ListItemPromptProps = Pick<InlinePromptProps, 'children' | 'sentimen
|
|
|
12
12
|
*
|
|
13
13
|
* Please refer to the [Design documentation](https://wise.design/components/list-item#prompt) for details.
|
|
14
14
|
*/
|
|
15
|
-
export const Prompt = ({
|
|
15
|
+
export const Prompt = ({
|
|
16
|
+
sentiment = Sentiment.NEUTRAL,
|
|
17
|
+
iconLabel,
|
|
18
|
+
children,
|
|
19
|
+
}: ListItemPromptProps) => {
|
|
16
20
|
const { ids, props } = useContext<ListItemContextData>(ListItemContext);
|
|
17
21
|
const isLongLivedMuted = props.disabled && Boolean(props.disabledPromptMessage);
|
|
18
22
|
|
|
@@ -20,6 +24,7 @@ export const Prompt = ({ sentiment = Sentiment.NEUTRAL, children }: ListItemProm
|
|
|
20
24
|
<InlinePrompt
|
|
21
25
|
id={ids.prompt}
|
|
22
26
|
sentiment={sentiment}
|
|
27
|
+
iconLabel={iconLabel}
|
|
23
28
|
muted={isLongLivedMuted}
|
|
24
29
|
className="wds-list-item-prompt"
|
|
25
30
|
>
|
|
@@ -26,7 +26,7 @@ describe('InlinePrompt', () => {
|
|
|
26
26
|
{ sentiment: Sentiment.NEGATIVE as const, acceptsMedia: false, statusIconLabel: 'Error:' },
|
|
27
27
|
{ sentiment: Sentiment.WARNING as const, acceptsMedia: false, statusIconLabel: 'Warning:' },
|
|
28
28
|
{ sentiment: Sentiment.NEUTRAL as const, acceptsMedia: false, statusIconLabel: 'Information:' },
|
|
29
|
-
{ sentiment: Sentiment.POSITIVE as const, acceptsMedia: true, statusIconLabel: '' },
|
|
29
|
+
{ sentiment: Sentiment.POSITIVE as const, acceptsMedia: true, statusIconLabel: 'Success:' },
|
|
30
30
|
{ sentiment: 'proposition' as const, acceptsMedia: true, statusIconLabel: '' },
|
|
31
31
|
].forEach(({ sentiment, statusIconLabel, acceptsMedia }) => {
|
|
32
32
|
describe(sentiment, () => {
|
|
@@ -90,6 +90,34 @@ describe('InlinePrompt', () => {
|
|
|
90
90
|
});
|
|
91
91
|
}
|
|
92
92
|
});
|
|
93
|
+
|
|
94
|
+
describe('iconLabel', () => {
|
|
95
|
+
const iconLabel = 'Custom icon label';
|
|
96
|
+
|
|
97
|
+
if (!statusIconLabel) {
|
|
98
|
+
it('should not have accessible name for the icon', () => {
|
|
99
|
+
const { container } = render(<InlinePrompt {...defaultProps} sentiment={sentiment} />);
|
|
100
|
+
expect(container.querySelector('svg')).not.toHaveAccessibleName();
|
|
101
|
+
});
|
|
102
|
+
} else {
|
|
103
|
+
it('should use default aria label', () => {
|
|
104
|
+
render(<InlinePrompt {...defaultProps} sentiment={sentiment} />);
|
|
105
|
+
expect(screen.getByLabelText(statusIconLabel)).toBeInTheDocument();
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
it('should allow for customisation of aria label', () => {
|
|
110
|
+
render(<InlinePrompt {...defaultProps} sentiment={sentiment} iconLabel={iconLabel} />);
|
|
111
|
+
expect(screen.getByLabelText(iconLabel)).toBeInTheDocument();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
it('should retain custom label while muted', () => {
|
|
115
|
+
render(
|
|
116
|
+
<InlinePrompt {...defaultProps} sentiment={sentiment} iconLabel={iconLabel} muted />,
|
|
117
|
+
);
|
|
118
|
+
expect(screen.getByLabelText(iconLabel)).toBeInTheDocument();
|
|
119
|
+
});
|
|
120
|
+
});
|
|
93
121
|
});
|
|
94
122
|
});
|
|
95
123
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { ReactElement } from 'react';
|
|
2
2
|
import type { Meta, StoryObj } from '@storybook/react-webpack5';
|
|
3
|
+
import { action } from 'storybook/actions';
|
|
3
4
|
import { Taxi, Travel } from '@transferwise/icons';
|
|
4
5
|
import { lorem5 } from '../../test-utils';
|
|
5
6
|
import Link from '../../link';
|
|
@@ -22,8 +23,9 @@ const withComponentGrid =
|
|
|
22
23
|
);
|
|
23
24
|
|
|
24
25
|
export default {
|
|
25
|
-
title: '
|
|
26
|
+
title: 'Prompts/InlinePrompt',
|
|
26
27
|
component: InlinePrompt,
|
|
28
|
+
tags: ['new'],
|
|
27
29
|
args: {
|
|
28
30
|
loading: false,
|
|
29
31
|
muted: false,
|
|
@@ -158,6 +160,39 @@ export const Loading: StoryObj<PreviewStoryArgs> = {
|
|
|
158
160
|
},
|
|
159
161
|
};
|
|
160
162
|
|
|
163
|
+
/**
|
|
164
|
+
* `InlinePrompt` can include a single instance of the `Link` component, which can be rendered as
|
|
165
|
+
* either HTML anchor or button. That element will spread across the whole surface of the Prompt
|
|
166
|
+
* so it's more accessible for motor–impaired and touch devices users.
|
|
167
|
+
*
|
|
168
|
+
* > ⚠️ For that reason it's crucial to only include **one** interactive element inside a prompt.
|
|
169
|
+
*/
|
|
170
|
+
export const Interactivity: StoryObj<PreviewStoryArgs> = {
|
|
171
|
+
argTypes: previewArgTypes,
|
|
172
|
+
args: {
|
|
173
|
+
muted: true,
|
|
174
|
+
previewMedia: false,
|
|
175
|
+
},
|
|
176
|
+
render: (args: PreviewStoryArgs) => (
|
|
177
|
+
<>
|
|
178
|
+
<InlinePrompt sentiment={args.sentiment}>
|
|
179
|
+
This prompt includes a{' '}
|
|
180
|
+
<Link href="https://wise.com" target="_blank" rel="noreferrer">
|
|
181
|
+
link to some resource
|
|
182
|
+
</Link>{' '}
|
|
183
|
+
to help the user in their journey.
|
|
184
|
+
</InlinePrompt>
|
|
185
|
+
|
|
186
|
+
<InlinePrompt sentiment={args.sentiment}>
|
|
187
|
+
{/* eslint-disable-next-line jsx-a11y/click-events-have-key-events */}
|
|
188
|
+
This prompt includes an <Link onClick={action('inline button')}>inline button</Link> than
|
|
189
|
+
can e.g. trigger a modal.
|
|
190
|
+
</InlinePrompt>
|
|
191
|
+
</>
|
|
192
|
+
),
|
|
193
|
+
decorators: [withComponentGrid()],
|
|
194
|
+
};
|
|
195
|
+
|
|
161
196
|
/**
|
|
162
197
|
* Inline prompt is usually associated with a different component, such as `Input` or `ListItem`.
|
|
163
198
|
* When those components are disabled, the prompt is often used to communicate to the user why they
|
|
@@ -174,14 +209,20 @@ export const Muted: StoryObj<PreviewStoryArgs> = {
|
|
|
174
209
|
},
|
|
175
210
|
render: (args: PreviewStoryArgs) => {
|
|
176
211
|
const [props, previewProps] = getPropsForPreview(args);
|
|
177
|
-
return
|
|
212
|
+
return (
|
|
213
|
+
<InlinePrompt {...props} {...previewProps}>
|
|
214
|
+
Please <Link href="#">confirm your residential address</Link> to activate this feature.
|
|
215
|
+
</InlinePrompt>
|
|
216
|
+
);
|
|
178
217
|
},
|
|
179
218
|
};
|
|
180
219
|
|
|
181
220
|
/**
|
|
182
221
|
* While main sentiments (`warning`, `negative`, `neutral`) must retain their associated
|
|
183
222
|
* `StatusIcons`, the `positive` and `proposition` ones allow for Icon overrides to bring it
|
|
184
|
-
* closer to the prompt's content.
|
|
223
|
+
* closer to the prompt's content. <br /><br />
|
|
224
|
+
* It's also possible to override the default icon's accessible name announced by screen readers
|
|
225
|
+
* via `iconLabel` prop, which is especially useful for the `proposition` sentiment.
|
|
185
226
|
*/
|
|
186
227
|
export const IconOverrides: StoryObj<PreviewStoryArgs> = {
|
|
187
228
|
render: (args: PreviewStoryArgs) => {
|
|
@@ -190,7 +231,7 @@ export const IconOverrides: StoryObj<PreviewStoryArgs> = {
|
|
|
190
231
|
<InlinePrompt {...args} media={<Travel />} sentiment="positive">
|
|
191
232
|
Your travel account is set up and ready to use.
|
|
192
233
|
</InlinePrompt>
|
|
193
|
-
<InlinePrompt {...args} media={<Taxi />} sentiment="proposition">
|
|
234
|
+
<InlinePrompt {...args} media={<Taxi />} sentiment="proposition" iconLabel="Taxi addon: ">
|
|
194
235
|
Connect Wise with your taxi app to get exclusive discounts.
|
|
195
236
|
</InlinePrompt>
|
|
196
237
|
<InlinePrompt {...args} media={<Taxi />} sentiment="negative">
|
|
@@ -28,6 +28,11 @@ export type InlinePromptProps = {
|
|
|
28
28
|
* Icon override for `proposition` and `positive` sentiments. Unsupported for remaining ones.
|
|
29
29
|
*/
|
|
30
30
|
media?: React.ReactNode;
|
|
31
|
+
/**
|
|
32
|
+
* Override for the sentiment's-derived, default, accessible name announced by the screen readers.
|
|
33
|
+
* To be used primarily for `proposition` sentiment.
|
|
34
|
+
*/
|
|
35
|
+
iconLabel?: string;
|
|
31
36
|
id?: string;
|
|
32
37
|
className?: string;
|
|
33
38
|
'data-testid'?: string;
|
|
@@ -36,7 +41,9 @@ export type InlinePromptProps = {
|
|
|
36
41
|
|
|
37
42
|
/**
|
|
38
43
|
* Inline prompts appear alongside a specific component on the screen. They help the user stay
|
|
39
|
-
* informed, fix something, or get more out of what they're doing.
|
|
44
|
+
* informed, fix something, or get more out of what they're doing. <br />
|
|
45
|
+
*
|
|
46
|
+
* **NB:** It should be used in favour of `InlineAlert` which will be soon deprecated.
|
|
40
47
|
*/
|
|
41
48
|
export const InlinePrompt = ({
|
|
42
49
|
sentiment = Sentiment.POSITIVE,
|
|
@@ -45,6 +52,7 @@ export const InlinePrompt = ({
|
|
|
45
52
|
className,
|
|
46
53
|
children,
|
|
47
54
|
media = null,
|
|
55
|
+
iconLabel,
|
|
48
56
|
'data-testid': dataTestId,
|
|
49
57
|
...rest
|
|
50
58
|
}: InlinePromptProps) => {
|
|
@@ -52,7 +60,7 @@ export const InlinePrompt = ({
|
|
|
52
60
|
|
|
53
61
|
const renderMedia = () => {
|
|
54
62
|
if (muted) {
|
|
55
|
-
return <BackslashCircle size={16} data-testid="InlinePrompt_Muted" />;
|
|
63
|
+
return <BackslashCircle size={16} data-testid="InlinePrompt_Muted" title={iconLabel} />;
|
|
56
64
|
}
|
|
57
65
|
if (loading) {
|
|
58
66
|
return (
|
|
@@ -69,10 +77,10 @@ export const InlinePrompt = ({
|
|
|
69
77
|
}
|
|
70
78
|
|
|
71
79
|
if (sentiment === 'proposition') {
|
|
72
|
-
return media || <GiftBox />;
|
|
80
|
+
return media || <GiftBox title={iconLabel} />;
|
|
73
81
|
}
|
|
74
82
|
|
|
75
|
-
return <StatusIcon size={16} sentiment={sentiment} />;
|
|
83
|
+
return <StatusIcon size={16} sentiment={sentiment} iconLabel={iconLabel} />;
|
|
76
84
|
};
|
|
77
85
|
|
|
78
86
|
return (
|
|
@@ -22,7 +22,7 @@ function ThemeProvider(props: ThemeProviderProps) {
|
|
|
22
22
|
|
|
23
23
|
export default {
|
|
24
24
|
component: ThemeProvider,
|
|
25
|
-
title: '
|
|
25
|
+
title: 'Foundations/ThemeProvider',
|
|
26
26
|
} satisfies Meta<typeof ThemeProvider>;
|
|
27
27
|
|
|
28
28
|
type Story = StoryObj<typeof ThemeProvider>;
|