@transferwise/components 0.0.0-experimental-9741cfd → 0.0.0-experimental-2d733a4
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/dateInput/DateInput.js +1 -1
- package/build/dateInput/DateInput.js.map +1 -1
- package/build/dateInput/DateInput.mjs +1 -1
- package/build/dateInput/DateInput.mjs.map +1 -1
- package/build/index.js +1 -0
- package/build/index.js.map +1 -1
- package/build/index.mjs +1 -1
- package/build/main.css +189 -8
- package/build/styles/dateInput/DateInput.css +1 -8
- package/build/styles/listItem/ListItem.css +188 -0
- package/build/styles/main.css +189 -8
- package/build/test-utils/assets/apple-pay-logo.svg +84 -0
- package/build/types/index.d.ts +2 -0
- package/build/types/index.d.ts.map +1 -1
- package/build/types/listItem/ListItem.d.ts +45 -0
- package/build/types/listItem/ListItem.d.ts.map +1 -0
- package/build/types/listItem/ListItemAdditionalInfo.d.ts +9 -0
- package/build/types/listItem/ListItemAdditionalInfo.d.ts.map +1 -0
- package/build/types/listItem/ListItemButton.d.ts +4 -0
- package/build/types/listItem/ListItemButton.d.ts.map +1 -0
- package/build/types/listItem/ListItemCheckbox.d.ts +4 -0
- package/build/types/listItem/ListItemCheckbox.d.ts.map +1 -0
- package/build/types/listItem/ListItemIconButton.d.ts +7 -0
- package/build/types/listItem/ListItemIconButton.d.ts.map +1 -0
- package/build/types/listItem/ListItemMedia.d.ts +19 -0
- package/build/types/listItem/ListItemMedia.d.ts.map +1 -0
- package/build/types/listItem/ListItemNavigation.d.ts +4 -0
- package/build/types/listItem/ListItemNavigation.d.ts.map +1 -0
- package/build/types/listItem/ListItemSwitch.d.ts +3 -0
- package/build/types/listItem/ListItemSwitch.d.ts.map +1 -0
- package/build/types/listItem/index.d.ts +6 -0
- package/build/types/listItem/index.d.ts.map +1 -0
- package/build/types/listItem/prompt/Prompt.d.ts +12 -0
- package/build/types/listItem/prompt/Prompt.d.ts.map +1 -0
- package/build/types/listItem/useItemControl.d.ts +12 -0
- package/build/types/listItem/useItemControl.d.ts.map +1 -0
- package/build/types/test-utils/fake-data.d.ts +2 -0
- package/build/types/test-utils/fake-data.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/dateInput/DateInput.css +1 -8
- package/src/dateInput/DateInput.less +3 -15
- package/src/dateInput/DateInput.tests.story.tsx +2 -8
- package/src/dateInput/DateInput.tsx +1 -1
- package/src/index.ts +2 -0
- package/src/legacylistItem/LegacyListItem.story.tsx +5 -5
- package/src/legacylistItem/LegacyListItem.tests.story.tsx +6 -6
- package/src/listItem/ListItem.css +188 -0
- package/src/listItem/ListItem.less +180 -0
- package/src/listItem/ListItem.spec.tsx +35 -0
- package/src/listItem/ListItem.story.tsx +329 -0
- package/src/listItem/ListItem.tsx +200 -0
- package/src/listItem/ListItemAdditionalInfo.tsx +31 -0
- package/src/listItem/ListItemButton.spec.tsx +90 -0
- package/src/listItem/ListItemButton.tsx +18 -0
- package/src/listItem/ListItemCheckbox.tsx +14 -0
- package/src/listItem/ListItemIconButton.tsx +13 -0
- package/src/listItem/ListItemMedia.tsx +52 -0
- package/src/listItem/ListItemNavigation.tsx +11 -0
- package/src/listItem/ListItemSwitch.tsx +8 -0
- package/src/listItem/index.ts +10 -0
- package/src/listItem/prompt/Prompt.spec.tsx +77 -0
- package/src/listItem/prompt/Prompt.story.tsx +170 -0
- package/src/listItem/prompt/Prompt.tsx +44 -0
- package/src/listItem/useItemControl.tsx +16 -0
- package/src/main.css +189 -8
- package/src/main.less +1 -0
- package/src/test-utils/assets/apple-pay-logo.svg +84 -0
- package/src/test-utils/fake-data.ts +5 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { default as ButtonComp, NewButtonProps } from '../button';
|
|
2
|
+
import { useItemControl } from './useItemControl';
|
|
3
|
+
|
|
4
|
+
export type ListItemButtonProps = Omit<NewButtonProps, 'v2' | 'size' | 'disabled'>;
|
|
5
|
+
|
|
6
|
+
export const Button = ({ priority = 'secondary', ...props }: ListItemButtonProps) => {
|
|
7
|
+
const { ids, baseItemProps } = useItemControl('button');
|
|
8
|
+
|
|
9
|
+
const commonProps = {
|
|
10
|
+
...props,
|
|
11
|
+
priority,
|
|
12
|
+
v2: true,
|
|
13
|
+
size: 'md',
|
|
14
|
+
disabled: baseItemProps.disabled,
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
return <ButtonComp {...(commonProps as NewButtonProps)} id={ids.control} />;
|
|
18
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import CheckboxButton from '../checkboxButton';
|
|
2
|
+
import { CheckboxButtonProps } from '../checkboxButton/CheckboxButton';
|
|
3
|
+
import { useItemControl } from './useItemControl';
|
|
4
|
+
|
|
5
|
+
export type ListItemCheckboxProps = Pick<
|
|
6
|
+
CheckboxButtonProps,
|
|
7
|
+
'checked' | 'indeterminate' | 'onChange'
|
|
8
|
+
>;
|
|
9
|
+
|
|
10
|
+
export const Checkbox = function (props: ListItemCheckboxProps) {
|
|
11
|
+
const { baseItemProps } = useItemControl('checkbox');
|
|
12
|
+
|
|
13
|
+
return <CheckboxButton disabled={baseItemProps.disabled} {...props} />;
|
|
14
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { default as IconButtonComp, IconButtonProps } from '../iconButton';
|
|
2
|
+
import { useItemControl } from './useItemControl';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
4
|
+
|
|
5
|
+
export type ListItemIconButtonProps = Pick<IconButtonProps, 'onClick' | 'href' | 'target'> & {
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
export const IconButton = function (props: ListItemIconButtonProps) {
|
|
10
|
+
const { baseItemProps } = useItemControl('icon-button');
|
|
11
|
+
|
|
12
|
+
return <IconButtonComp {...props} size={32} disabled={baseItemProps.disabled} />;
|
|
13
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { default as AvatarViewComp, AvatarViewProps } from '../avatarView';
|
|
2
|
+
import { default as AvatarLayoutComp, AvatarLayoutProps } from '../avatarLayout';
|
|
3
|
+
import { default as ImageComp, ImageProps } from '../image/Image';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
|
|
6
|
+
type SizeProp = { size?: 32 | 40 | 48 | 56 | 72 };
|
|
7
|
+
|
|
8
|
+
export type ListItemAvatarViewProps = Omit<AvatarViewProps, 'size' | 'interactive'> & SizeProp;
|
|
9
|
+
|
|
10
|
+
export const AvatarView = ({ className, size = 48, ...props }: ListItemAvatarViewProps) => {
|
|
11
|
+
return (
|
|
12
|
+
<AvatarViewComp
|
|
13
|
+
{...props}
|
|
14
|
+
size={size}
|
|
15
|
+
className={clsx('wds-list-item-media-avatar-view', className)}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
export type ListItemAvatarLayoutProps = Omit<AvatarLayoutProps, 'size' | 'interactive'> & SizeProp;
|
|
21
|
+
|
|
22
|
+
export const AvatarLayout = ({ className, size = 48, ...props }: ListItemAvatarLayoutProps) => {
|
|
23
|
+
return (
|
|
24
|
+
<AvatarLayoutComp
|
|
25
|
+
{...props}
|
|
26
|
+
size={size}
|
|
27
|
+
className={clsx('wds-list-item-media-avatar-layout', className)}
|
|
28
|
+
/>
|
|
29
|
+
);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
export type ListItemImageProps = Omit<ImageProps, 'stretch' | 'shrink' | 'id' | 'alt'> &
|
|
33
|
+
SizeProp & {
|
|
34
|
+
alt?: string;
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* TODO: mention that image is for rare cases not for DS illustrations, they discouraged
|
|
39
|
+
*/
|
|
40
|
+
export const Image = ({ alt = '', size = 48, ...props }: ListItemImageProps) => {
|
|
41
|
+
return (
|
|
42
|
+
<div
|
|
43
|
+
className={clsx('wds-list-item-media-image')}
|
|
44
|
+
style={{
|
|
45
|
+
// @ts-expect-error CSS custom props allowed
|
|
46
|
+
'--item-media-image-size': `${size}px`,
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<ImageComp {...props} alt={alt} />
|
|
50
|
+
</div>
|
|
51
|
+
);
|
|
52
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ChevronRight, BillSplit as Disabled } from '@transferwise/icons';
|
|
2
|
+
import { ButtonProps } from '../button/Button.types';
|
|
3
|
+
import { useItemControl } from './useItemControl';
|
|
4
|
+
|
|
5
|
+
export type ListItemNavigationProps = Pick<ButtonProps, 'onClick' | 'href'>;
|
|
6
|
+
|
|
7
|
+
export const Navigation = function Navigation({ onClick }: ListItemNavigationProps) {
|
|
8
|
+
const { baseItemProps } = useItemControl('navigation');
|
|
9
|
+
|
|
10
|
+
return baseItemProps.disabled ? <Disabled size={24} /> : <ChevronRight size={24} />;
|
|
11
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { default as SwitchComp, SwitchProps } from '../switch';
|
|
2
|
+
import { useItemControl } from './useItemControl';
|
|
3
|
+
|
|
4
|
+
export const Switch = function (props: SwitchProps) {
|
|
5
|
+
const { baseItemProps } = useItemControl('switch');
|
|
6
|
+
|
|
7
|
+
return <SwitchComp disabled={baseItemProps.disabled} {...props} />;
|
|
8
|
+
};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { Props as ListItemProps } from './ListItem';
|
|
2
|
+
export type { ListItemAdditionalInfoProps } from './ListItemAdditionalInfo';
|
|
3
|
+
export type { ListItemCheckboxProps } from './ListItemCheckbox';
|
|
4
|
+
export type {
|
|
5
|
+
ListItemImageProps,
|
|
6
|
+
ListItemAvatarViewProps,
|
|
7
|
+
ListItemAvatarLayoutProps,
|
|
8
|
+
} from './ListItemMedia';
|
|
9
|
+
|
|
10
|
+
export { default } from './ListItem';
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { render, screen, mockMatchMedia } from '../../test-utils';
|
|
2
|
+
import { Prompt } from './Prompt';
|
|
3
|
+
import { Sentiment } from '../../common';
|
|
4
|
+
|
|
5
|
+
mockMatchMedia();
|
|
6
|
+
|
|
7
|
+
describe('ListItem.Prompt', () => {
|
|
8
|
+
it('renders the aria-label when provided', () => {
|
|
9
|
+
const ariaLabel = 'Test aria-label';
|
|
10
|
+
render(
|
|
11
|
+
<Prompt
|
|
12
|
+
type={Sentiment.POSITIVE}
|
|
13
|
+
action={{ 'aria-label': ariaLabel, href: 'https://example.com' }}
|
|
14
|
+
>
|
|
15
|
+
Positive prompt
|
|
16
|
+
</Prompt>,
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
expect(screen.getByLabelText(ariaLabel)).toBeInTheDocument();
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('applies the interactive class when href is provided', () => {
|
|
23
|
+
render(
|
|
24
|
+
<Prompt
|
|
25
|
+
type={Sentiment.POSITIVE}
|
|
26
|
+
action={{ href: 'https://example.com', 'aria-label': 'Interactive link' }}
|
|
27
|
+
>
|
|
28
|
+
Interactive link
|
|
29
|
+
</Prompt>,
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
expect(screen.getByRole('link')).toHaveClass('np-prompt-interactive');
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
it('applies the interactive class when onClick is provided', () => {
|
|
36
|
+
render(
|
|
37
|
+
<Prompt
|
|
38
|
+
type={Sentiment.POSITIVE}
|
|
39
|
+
action={{ onClick: jest.fn(), 'aria-label': 'Interactive button' }}
|
|
40
|
+
>
|
|
41
|
+
Interactive button
|
|
42
|
+
</Prompt>,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
expect(screen.getByRole('button')).toHaveClass('np-prompt-interactive');
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
it('does not apply the interactive class when no action is provided', () => {
|
|
49
|
+
render(<Prompt type={Sentiment.POSITIVE}>Non-interactive prompt</Prompt>);
|
|
50
|
+
|
|
51
|
+
expect(screen.getByText('Non-interactive prompt')).not.toHaveClass('np-prompt-interactive');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('renders the children content', () => {
|
|
55
|
+
render(<Prompt type={Sentiment.POSITIVE}>This is a child prompt</Prompt>);
|
|
56
|
+
|
|
57
|
+
expect(screen.getByText('This is a child prompt')).toBeInTheDocument();
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
it('spreads additional props to the wrapper element', () => {
|
|
61
|
+
render(
|
|
62
|
+
<Prompt
|
|
63
|
+
type={Sentiment.POSITIVE}
|
|
64
|
+
action={{
|
|
65
|
+
href: 'https://example.com',
|
|
66
|
+
target: '_blank',
|
|
67
|
+
'aria-label': 'Custom props prompt',
|
|
68
|
+
}}
|
|
69
|
+
>
|
|
70
|
+
Custom props prompt
|
|
71
|
+
</Prompt>,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const link = screen.getByRole('link');
|
|
75
|
+
expect(link).toHaveAttribute('target', '_blank');
|
|
76
|
+
});
|
|
77
|
+
});
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
import Link from '../../link';
|
|
2
|
+
import { Sentiment } from '../../common';
|
|
3
|
+
import { Prompt, ListItemPromptProps } from './Prompt';
|
|
4
|
+
import { lorem40 } from '../../test-utils';
|
|
5
|
+
import { StoryObj } from '@storybook/react';
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
component: Prompt,
|
|
9
|
+
title: 'Content/ListItem/Prompt',
|
|
10
|
+
args: {
|
|
11
|
+
type: Sentiment.NEGATIVE,
|
|
12
|
+
children: 'You have done a terrible thing',
|
|
13
|
+
},
|
|
14
|
+
argTypes: {
|
|
15
|
+
type: {
|
|
16
|
+
options: [
|
|
17
|
+
Sentiment.POSITIVE,
|
|
18
|
+
Sentiment.NEGATIVE,
|
|
19
|
+
Sentiment.NEUTRAL,
|
|
20
|
+
Sentiment.WARNING,
|
|
21
|
+
'discount',
|
|
22
|
+
'savings',
|
|
23
|
+
],
|
|
24
|
+
control: { type: 'radio' },
|
|
25
|
+
description: 'The type of prompt to display',
|
|
26
|
+
},
|
|
27
|
+
action: {
|
|
28
|
+
table: {
|
|
29
|
+
disable: true,
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
children: {
|
|
33
|
+
type: {
|
|
34
|
+
name: 'string',
|
|
35
|
+
required: true,
|
|
36
|
+
description: 'The content of the prompt',
|
|
37
|
+
},
|
|
38
|
+
},
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
type CustomStory = StoryObj<
|
|
43
|
+
ListItemPromptProps & {
|
|
44
|
+
interactivity?: 'none' | 'full-anchor' | 'full-button' | 'link';
|
|
45
|
+
}
|
|
46
|
+
>;
|
|
47
|
+
|
|
48
|
+
export const Basic: CustomStory = {
|
|
49
|
+
args: {
|
|
50
|
+
interactivity: 'none',
|
|
51
|
+
},
|
|
52
|
+
argTypes: {
|
|
53
|
+
interactivity: {
|
|
54
|
+
options: ['none', 'full-button', 'full-anchor', 'link'],
|
|
55
|
+
control: { type: 'radio' },
|
|
56
|
+
description: 'The type of interactivity to display',
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
render: ({ interactivity, ...args }) => {
|
|
60
|
+
return (
|
|
61
|
+
<div>
|
|
62
|
+
<Prompt
|
|
63
|
+
type={args.type}
|
|
64
|
+
action={
|
|
65
|
+
interactivity === 'full-anchor'
|
|
66
|
+
? { href: 'wise.com' }
|
|
67
|
+
: interactivity === 'full-button'
|
|
68
|
+
? {
|
|
69
|
+
onClick: () => {
|
|
70
|
+
console.log('clicked');
|
|
71
|
+
},
|
|
72
|
+
}
|
|
73
|
+
: undefined
|
|
74
|
+
}
|
|
75
|
+
>
|
|
76
|
+
{args.children} {interactivity === 'link' && <Link href="www.wise.com">with a link</Link>}
|
|
77
|
+
</Prompt>
|
|
78
|
+
</div>
|
|
79
|
+
);
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
export const Variants = () => {
|
|
84
|
+
return (
|
|
85
|
+
<>
|
|
86
|
+
<div className="m-b-2">
|
|
87
|
+
<Prompt type={Sentiment.POSITIVE}>
|
|
88
|
+
Positive prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
89
|
+
</Prompt>
|
|
90
|
+
</div>
|
|
91
|
+
<div className="m-b-2">
|
|
92
|
+
<Prompt type={Sentiment.NEGATIVE}>
|
|
93
|
+
Negative prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
94
|
+
</Prompt>
|
|
95
|
+
</div>
|
|
96
|
+
<div className="m-b-2">
|
|
97
|
+
<Prompt type={Sentiment.NEUTRAL}>
|
|
98
|
+
Neutral prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
99
|
+
</Prompt>
|
|
100
|
+
</div>
|
|
101
|
+
<div className="m-b-2">
|
|
102
|
+
<Prompt type={Sentiment.WARNING}>
|
|
103
|
+
Warning prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
104
|
+
</Prompt>
|
|
105
|
+
</div>
|
|
106
|
+
<div className="m-b-2">
|
|
107
|
+
<Prompt type="discount">
|
|
108
|
+
Discount prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
109
|
+
</Prompt>
|
|
110
|
+
</div>
|
|
111
|
+
<div className="m-b-2">
|
|
112
|
+
<Prompt type="savings">
|
|
113
|
+
Savings prompt <Link href="www.wise.com">with a link to amazing content</Link>
|
|
114
|
+
</Prompt>
|
|
115
|
+
</div>
|
|
116
|
+
<div className="m-b-2">
|
|
117
|
+
<Prompt
|
|
118
|
+
type="discount"
|
|
119
|
+
action={{
|
|
120
|
+
href: 'www.wise.com',
|
|
121
|
+
target: '_self',
|
|
122
|
+
'aria-label': 'hidden anchor tags are accessible, right?',
|
|
123
|
+
}}
|
|
124
|
+
>
|
|
125
|
+
The whole prompt is secretly clickable
|
|
126
|
+
</Prompt>
|
|
127
|
+
</div>
|
|
128
|
+
<div className="m-b-2">
|
|
129
|
+
<Prompt
|
|
130
|
+
type="negative"
|
|
131
|
+
action={{
|
|
132
|
+
href: 'www.wise.com',
|
|
133
|
+
target: '_self',
|
|
134
|
+
'aria-label': 'clickable <a>',
|
|
135
|
+
}}
|
|
136
|
+
>
|
|
137
|
+
The whole prompt is secretly clickable as an anchor tag
|
|
138
|
+
</Prompt>
|
|
139
|
+
</div>
|
|
140
|
+
<div className="m-b-2">
|
|
141
|
+
<Prompt
|
|
142
|
+
type="warning"
|
|
143
|
+
action={{
|
|
144
|
+
onClick: () => {
|
|
145
|
+
console.log('clicked');
|
|
146
|
+
},
|
|
147
|
+
'aria-label': 'clickable button',
|
|
148
|
+
}}
|
|
149
|
+
>
|
|
150
|
+
The whole prompt is secretly clickable as a button
|
|
151
|
+
</Prompt>
|
|
152
|
+
</div>
|
|
153
|
+
<div className="m-b-2">
|
|
154
|
+
<Prompt
|
|
155
|
+
type="neutral"
|
|
156
|
+
action={{
|
|
157
|
+
href: 'www.wise.com',
|
|
158
|
+
target: '_self',
|
|
159
|
+
'aria-label': 'clickable prompt',
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
The whole prompt is secretly clickable
|
|
163
|
+
</Prompt>
|
|
164
|
+
</div>
|
|
165
|
+
<div className="m-b-2" style={{ maxWidth: '300px' }}>
|
|
166
|
+
<Prompt type="warning">The prompt has very long text that wraps {lorem40}</Prompt>
|
|
167
|
+
</div>
|
|
168
|
+
</>
|
|
169
|
+
);
|
|
170
|
+
};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { Confetti, Tags } from '@transferwise/icons';
|
|
2
|
+
import { Sentiment } from '../../common';
|
|
3
|
+
import StatusIcon from '../../statusIcon';
|
|
4
|
+
import { clsx } from 'clsx';
|
|
5
|
+
import { LinkProps } from '../../link';
|
|
6
|
+
import Body from '../../body';
|
|
7
|
+
|
|
8
|
+
export type ListItemPromptProps = {
|
|
9
|
+
type:
|
|
10
|
+
| `${Sentiment.POSITIVE | Sentiment.NEGATIVE | Sentiment.NEUTRAL | Sentiment.WARNING}`
|
|
11
|
+
| 'discount'
|
|
12
|
+
| 'savings';
|
|
13
|
+
children: React.ReactNode;
|
|
14
|
+
action?: Pick<LinkProps, 'href' | 'target' | 'onClick'> & { 'aria-label'?: string };
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export const Prompt = ({ type, children, action }: ListItemPromptProps) => {
|
|
18
|
+
const Wrapper = action?.href ? 'a' : action?.onClick ? 'button' : 'span';
|
|
19
|
+
|
|
20
|
+
const icon =
|
|
21
|
+
type === 'discount' ? (
|
|
22
|
+
<Tags size={16} />
|
|
23
|
+
) : type === 'savings' ? (
|
|
24
|
+
<Confetti size={16} />
|
|
25
|
+
) : (
|
|
26
|
+
<StatusIcon size={16} sentiment={type} />
|
|
27
|
+
);
|
|
28
|
+
|
|
29
|
+
return (
|
|
30
|
+
<Wrapper
|
|
31
|
+
className={clsx(
|
|
32
|
+
'wds-list-item-prompt',
|
|
33
|
+
type,
|
|
34
|
+
(action?.href || action?.onClick) && 'np-prompt-interactive',
|
|
35
|
+
)}
|
|
36
|
+
{...(action ?? {})}
|
|
37
|
+
>
|
|
38
|
+
<div className="np-prompt-icon">{icon}</div>
|
|
39
|
+
<Body>{children}</Body>
|
|
40
|
+
</Wrapper>
|
|
41
|
+
);
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export default Prompt;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { useContext, useEffect } from 'react';
|
|
2
|
+
import { ListItemContext, ListItemContextData, ListItemTypes } from './ListItem';
|
|
3
|
+
|
|
4
|
+
export function useItemControl(controlType: ListItemTypes) {
|
|
5
|
+
const {
|
|
6
|
+
ids,
|
|
7
|
+
setControlType,
|
|
8
|
+
props: baseItemProps,
|
|
9
|
+
} = useContext<ListItemContextData>(ListItemContext);
|
|
10
|
+
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
setControlType(controlType);
|
|
13
|
+
}, [controlType, setControlType]);
|
|
14
|
+
|
|
15
|
+
return { ids, baseItemProps };
|
|
16
|
+
}
|
package/src/main.css
CHANGED
|
@@ -1910,17 +1910,10 @@ button.np-option {
|
|
|
1910
1910
|
border-color: rgba(0,0,0,0.10196);
|
|
1911
1911
|
border-color: var(--color-border-neutral);
|
|
1912
1912
|
}
|
|
1913
|
-
.tw-date label {
|
|
1913
|
+
.np-theme-personal .tw-date label {
|
|
1914
1914
|
width: 100%;
|
|
1915
|
-
}
|
|
1916
|
-
.tw-date .tw-date--year label {
|
|
1917
1915
|
margin-bottom: 0;
|
|
1918
1916
|
}
|
|
1919
|
-
@media (min-width: 576px) {
|
|
1920
|
-
.np-theme-personal .tw-date label {
|
|
1921
|
-
margin-bottom: 0;
|
|
1922
|
-
}
|
|
1923
|
-
}
|
|
1924
1917
|
.tw-date-lookup-menu {
|
|
1925
1918
|
width: 400px;
|
|
1926
1919
|
}
|
|
@@ -2669,6 +2662,194 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
2669
2662
|
border-radius: 9999px !important;
|
|
2670
2663
|
border-radius: var(--radius-full) !important;
|
|
2671
2664
|
}
|
|
2665
|
+
.wds-list-item {
|
|
2666
|
+
padding: 16px;
|
|
2667
|
+
padding: var(--size-16);
|
|
2668
|
+
border-radius: 16px;
|
|
2669
|
+
border-radius: var(--radius-medium);
|
|
2670
|
+
background-color: #ffffff;
|
|
2671
|
+
background-color: var(--color-background-screen);
|
|
2672
|
+
gap: 16px;
|
|
2673
|
+
gap: var(--size-16);
|
|
2674
|
+
}
|
|
2675
|
+
.wds-list-item-interactive {
|
|
2676
|
+
cursor: pointer;
|
|
2677
|
+
}
|
|
2678
|
+
.wds-list-item-interactive:hover {
|
|
2679
|
+
background-color: var(--color-background-screen-hover);
|
|
2680
|
+
}
|
|
2681
|
+
.wds-list-item-interactive:active {
|
|
2682
|
+
background-color: var(--color-background-screen-active);
|
|
2683
|
+
}
|
|
2684
|
+
.wds-list-item-media-image {
|
|
2685
|
+
width: var(--item-media-image-size);
|
|
2686
|
+
height: var(--item-media-image-size);
|
|
2687
|
+
}
|
|
2688
|
+
.wds-list-item-body {
|
|
2689
|
+
width: 100%;
|
|
2690
|
+
}
|
|
2691
|
+
.wds-list-item-title {
|
|
2692
|
+
color: #37517e;
|
|
2693
|
+
color: var(--color-content-primary);
|
|
2694
|
+
}
|
|
2695
|
+
.wds-list-item-additional-info {
|
|
2696
|
+
color: #768e9c;
|
|
2697
|
+
color: var(--color-content-tertiary);
|
|
2698
|
+
}
|
|
2699
|
+
.wds-list-item-value {
|
|
2700
|
+
flex: 0 0 auto;
|
|
2701
|
+
}
|
|
2702
|
+
.wds-list-item-control {
|
|
2703
|
+
flex: 0 0 auto;
|
|
2704
|
+
}
|
|
2705
|
+
.wds-list-item-spotlight-active {
|
|
2706
|
+
background-color: rgba(134,167,189,0.10196);
|
|
2707
|
+
background-color: var(--color-background-neutral);
|
|
2708
|
+
}
|
|
2709
|
+
.wds-list-item-spotlight-active:not(.disabled):not(:disabled):hover {
|
|
2710
|
+
background-color: var(--color-background-neutral-hover);
|
|
2711
|
+
}
|
|
2712
|
+
.wds-list-item-spotlight-active:not(.disabled):not(:disabled):active {
|
|
2713
|
+
background-color: var(--color-background-neutral-active);
|
|
2714
|
+
}
|
|
2715
|
+
.wds-list-item-spotlight-inactive {
|
|
2716
|
+
background-color: rgba(134, 167, 189, 0.025);
|
|
2717
|
+
border: 1px dashed rgba(0,0,0,0.10196);
|
|
2718
|
+
border: 1px dashed var(--color-border-neutral);
|
|
2719
|
+
}
|
|
2720
|
+
@supports (color: color-mix(in lch, red, blue)) {
|
|
2721
|
+
.wds-list-item-spotlight-inactive {
|
|
2722
|
+
background-color: color-mix(in srgb, var(--color-background-neutral) 25%, transparent);
|
|
2723
|
+
}
|
|
2724
|
+
}
|
|
2725
|
+
.wds-list-item-spotlight-inactive:not(.disabled):not(:disabled):hover {
|
|
2726
|
+
background-color: color-mix(in srgb, var(--color-background-neutral-hover) 25%, transparent);
|
|
2727
|
+
}
|
|
2728
|
+
.wds-list-item-spotlight-inactive:not(.disabled):not(:disabled):active {
|
|
2729
|
+
background-color: color-mix(in srgb, var(--color-background-neutral-active) 25%, transparent);
|
|
2730
|
+
}
|
|
2731
|
+
.wds-list-item-prompt {
|
|
2732
|
+
display: inline-flex;
|
|
2733
|
+
padding-top: calc(8px / 2);
|
|
2734
|
+
padding-top: calc(var(--padding-x-small) / 2);
|
|
2735
|
+
padding-bottom: calc(8px / 2);
|
|
2736
|
+
padding-bottom: calc(var(--padding-x-small) / 2);
|
|
2737
|
+
padding-left: calc(8px - 1px);
|
|
2738
|
+
padding-left: calc(var(--padding-x-small) - 1px);
|
|
2739
|
+
padding-right: 8px;
|
|
2740
|
+
padding-right: var(--padding-x-small);
|
|
2741
|
+
border-radius: 10px;
|
|
2742
|
+
border-radius: var(--radius-small);
|
|
2743
|
+
word-break: break-word;
|
|
2744
|
+
word-wrap: break-word;
|
|
2745
|
+
}
|
|
2746
|
+
.wds-list-item-prompt .np-prompt-icon {
|
|
2747
|
+
padding-right: calc(12px / 2);
|
|
2748
|
+
padding-right: calc(var(--size-12) / 2);
|
|
2749
|
+
padding-top: calc(4px - 1px);
|
|
2750
|
+
padding-top: calc(var(--size-4) - 1px);
|
|
2751
|
+
padding-bottom: calc(4px - 1px);
|
|
2752
|
+
padding-bottom: calc(var(--size-4) - 1px);
|
|
2753
|
+
}
|
|
2754
|
+
.wds-list-item-prompt .np-prompt-icon .tw-icon-tags,
|
|
2755
|
+
.wds-list-item-prompt .np-prompt-icon .tw-icon-confetti {
|
|
2756
|
+
color: var(--color-sentiment-positive-primary);
|
|
2757
|
+
}
|
|
2758
|
+
.wds-list-item-prompt a {
|
|
2759
|
+
text-underline-offset: calc(4px / 2);
|
|
2760
|
+
text-underline-offset: calc(var(--size-4) / 2);
|
|
2761
|
+
}
|
|
2762
|
+
.wds-list-item-prompt.np-prompt-interactive {
|
|
2763
|
+
-webkit-text-decoration: none;
|
|
2764
|
+
text-decoration: none;
|
|
2765
|
+
cursor: pointer;
|
|
2766
|
+
border: none;
|
|
2767
|
+
}
|
|
2768
|
+
.wds-list-item-prompt.negative {
|
|
2769
|
+
background-color: var(--color-sentiment-negative-secondary);
|
|
2770
|
+
color: var(--color-sentiment-negative-primary);
|
|
2771
|
+
}
|
|
2772
|
+
.wds-list-item-prompt.negative a {
|
|
2773
|
+
color: var(--color-sentiment-negative-primary);
|
|
2774
|
+
}
|
|
2775
|
+
.wds-list-item-prompt.negative a:hover {
|
|
2776
|
+
color: var(--color-sentiment-negative-primary-hover);
|
|
2777
|
+
}
|
|
2778
|
+
.wds-list-item-prompt.negative a:active {
|
|
2779
|
+
color: var(--color-sentiment-negative-primary-active);
|
|
2780
|
+
}
|
|
2781
|
+
.np-prompt-interactive.wds-list-item-prompt.negative:hover {
|
|
2782
|
+
background-color: color-mix(in srgb, var(--color-sentiment-negative-secondary) 95%, var(--color-sentiment-negative-primary));
|
|
2783
|
+
}
|
|
2784
|
+
.np-prompt-interactive.wds-list-item-prompt.negative:active {
|
|
2785
|
+
background-color: color-mix(in srgb, var(--color-sentiment-negative-secondary) 90%, var(--color-sentiment-negative-primary));
|
|
2786
|
+
}
|
|
2787
|
+
.wds-list-item-prompt.positive,
|
|
2788
|
+
.wds-list-item-prompt.discount,
|
|
2789
|
+
.wds-list-item-prompt.savings {
|
|
2790
|
+
background-color: var(--color-sentiment-positive-secondary);
|
|
2791
|
+
color: var(--color-sentiment-positive-primary);
|
|
2792
|
+
}
|
|
2793
|
+
.wds-list-item-prompt.positive a,
|
|
2794
|
+
.wds-list-item-prompt.discount a,
|
|
2795
|
+
.wds-list-item-prompt.savings a {
|
|
2796
|
+
color: var(--color-sentiment-positive-primary);
|
|
2797
|
+
}
|
|
2798
|
+
.wds-list-item-prompt.positive a:hover,
|
|
2799
|
+
.wds-list-item-prompt.discount a:hover,
|
|
2800
|
+
.wds-list-item-prompt.savings a:hover {
|
|
2801
|
+
color: var(--color-sentiment-positive-primary-hover);
|
|
2802
|
+
}
|
|
2803
|
+
.wds-list-item-prompt.positive a:active,
|
|
2804
|
+
.wds-list-item-prompt.discount a:active,
|
|
2805
|
+
.wds-list-item-prompt.savings a:active {
|
|
2806
|
+
color: var(--color-sentiment-positive-primary-active);
|
|
2807
|
+
}
|
|
2808
|
+
.np-prompt-interactive.wds-list-item-prompt.positive:hover,
|
|
2809
|
+
.np-prompt-interactive.wds-list-item-prompt.discount:hover,
|
|
2810
|
+
.np-prompt-interactive.wds-list-item-prompt.savings:hover {
|
|
2811
|
+
background-color: color-mix(in srgb, var(--color-sentiment-positive-secondary) 95%, var(--color-sentiment-positive-primary));
|
|
2812
|
+
}
|
|
2813
|
+
.np-prompt-interactive.wds-list-item-prompt.positive:active,
|
|
2814
|
+
.np-prompt-interactive.wds-list-item-prompt.discount:active,
|
|
2815
|
+
.np-prompt-interactive.wds-list-item-prompt.savings:active {
|
|
2816
|
+
background-color: color-mix(in srgb, var(--color-sentiment-positive-secondary) 90%, var(--color-sentiment-positive-primary));
|
|
2817
|
+
}
|
|
2818
|
+
.wds-list-item-prompt.neutral {
|
|
2819
|
+
background-color: rgba(134,167,189,0.10196);
|
|
2820
|
+
background-color: var(--color-background-neutral);
|
|
2821
|
+
color: #37517e;
|
|
2822
|
+
color: var(--color-content-primary);
|
|
2823
|
+
}
|
|
2824
|
+
.wds-list-item-prompt.neutral a {
|
|
2825
|
+
color: #37517e;
|
|
2826
|
+
color: var(--color-content-primary);
|
|
2827
|
+
}
|
|
2828
|
+
.np-prompt-interactive.wds-list-item-prompt.neutral:hover {
|
|
2829
|
+
background-color: var(--color-background-neutral-hover);
|
|
2830
|
+
}
|
|
2831
|
+
.np-prompt-interactive.wds-list-item-prompt.neutral:active {
|
|
2832
|
+
background-color: var(--color-background-neutral-active);
|
|
2833
|
+
}
|
|
2834
|
+
.wds-list-item-prompt.warning {
|
|
2835
|
+
background-color: var(--color-sentiment-warning-secondary);
|
|
2836
|
+
color: var(--color-sentiment-warning-content);
|
|
2837
|
+
}
|
|
2838
|
+
.wds-list-item-prompt.warning a {
|
|
2839
|
+
color: var(--color-sentiment-warning-content);
|
|
2840
|
+
}
|
|
2841
|
+
.wds-list-item-prompt.warning a:hover {
|
|
2842
|
+
color: var(--color-sentiment-warning-content-hover);
|
|
2843
|
+
}
|
|
2844
|
+
.wds-list-item-prompt.warning a:active {
|
|
2845
|
+
color: var(--color-sentiment-warning-content-active);
|
|
2846
|
+
}
|
|
2847
|
+
.np-prompt-interactive.wds-list-item-prompt.warning:hover {
|
|
2848
|
+
background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 90%, var(--color-sentiment-warning-primary));
|
|
2849
|
+
}
|
|
2850
|
+
.np-prompt-interactive.wds-list-item-prompt.warning:active {
|
|
2851
|
+
background-color: color-mix(in srgb, var(--color-sentiment-warning-secondary) 80%, var(--color-sentiment-warning-primary));
|
|
2852
|
+
}
|
|
2672
2853
|
.np-field-control {
|
|
2673
2854
|
margin-top: 4px;
|
|
2674
2855
|
margin-top: var(--size-4);
|
package/src/main.less
CHANGED