@transferwise/components 46.89.2 → 46.90.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/header/Header.js +6 -1
- package/build/header/Header.js.map +1 -1
- package/build/header/Header.mjs +6 -1
- package/build/header/Header.mjs.map +1 -1
- package/build/inputs/SelectInput.js +19 -8
- package/build/inputs/SelectInput.js.map +1 -1
- package/build/inputs/SelectInput.mjs +19 -8
- package/build/inputs/SelectInput.mjs.map +1 -1
- package/build/main.css +0 -4
- package/build/section/Section.js +5 -1
- package/build/section/Section.js.map +1 -1
- package/build/section/Section.mjs +5 -1
- package/build/section/Section.mjs.map +1 -1
- package/build/styles/inputs/SelectInput.css +0 -4
- package/build/styles/main.css +0 -4
- package/build/title/Title.js.map +1 -1
- package/build/title/Title.mjs.map +1 -1
- package/build/types/header/Header.d.ts +4 -3
- package/build/types/header/Header.d.ts.map +1 -1
- package/build/types/inputs/SelectInput.d.ts +5 -0
- package/build/types/inputs/SelectInput.d.ts.map +1 -1
- package/build/types/section/Section.d.ts +4 -4
- package/build/types/section/Section.d.ts.map +1 -1
- package/build/types/title/Title.d.ts +1 -1
- package/build/types/title/Title.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/header/Header.tsx +14 -4
- package/src/inputs/SelectInput.css +0 -4
- package/src/inputs/SelectInput.less +0 -2
- package/src/inputs/SelectInput.story.tsx +59 -0
- package/src/inputs/SelectInput.tsx +29 -12
- package/src/main.css +0 -4
- package/src/section/Section.tsx +8 -3
- package/src/title/Title.tsx +1 -1
|
@@ -290,6 +290,65 @@ export const MultipleCurrencies: Story<Currency, true> = {
|
|
|
290
290
|
},
|
|
291
291
|
};
|
|
292
292
|
|
|
293
|
+
export const WithSelectAll: Story<Currency, true> = {
|
|
294
|
+
args: {
|
|
295
|
+
...MultipleCurrencies.args,
|
|
296
|
+
},
|
|
297
|
+
render: function Render(args) {
|
|
298
|
+
const [selectedItems, setSelectedItems] = useState<Currency[]>([]);
|
|
299
|
+
|
|
300
|
+
const allSelected = (items: Currency[]) => {
|
|
301
|
+
const selectedSet = new Set(selectedItems);
|
|
302
|
+
return items.every((item) => selectedSet.has(item));
|
|
303
|
+
};
|
|
304
|
+
|
|
305
|
+
const toggleItems = (items: Currency[]) => {
|
|
306
|
+
setSelectedItems((currentItems) =>
|
|
307
|
+
allSelected(items)
|
|
308
|
+
? currentItems.filter((item) => !items.includes(item))
|
|
309
|
+
: [...new Set([...currentItems, ...items])],
|
|
310
|
+
);
|
|
311
|
+
};
|
|
312
|
+
|
|
313
|
+
return (
|
|
314
|
+
<SelectInput
|
|
315
|
+
{...args}
|
|
316
|
+
items={[
|
|
317
|
+
{
|
|
318
|
+
type: 'group',
|
|
319
|
+
label: 'Popular currencies',
|
|
320
|
+
options: popularCurrencies.map((currency) => currencyOption(currency)),
|
|
321
|
+
action: {
|
|
322
|
+
label: allSelected(popularCurrencies) ? 'Deselect all' : 'Select all',
|
|
323
|
+
onClick: () => {
|
|
324
|
+
toggleItems(popularCurrencies);
|
|
325
|
+
},
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
type: 'group',
|
|
330
|
+
label: 'Other currencies',
|
|
331
|
+
options: otherCurrencies.map((currency) => currencyOption(currency)),
|
|
332
|
+
action: {
|
|
333
|
+
label: allSelected(otherCurrencies) ? 'Deselect all' : 'Select all',
|
|
334
|
+
onClick: () => {
|
|
335
|
+
toggleItems(otherCurrencies);
|
|
336
|
+
},
|
|
337
|
+
},
|
|
338
|
+
},
|
|
339
|
+
]}
|
|
340
|
+
value={selectedItems}
|
|
341
|
+
onChange={(currencies) => {
|
|
342
|
+
setSelectedItems(currencies);
|
|
343
|
+
}}
|
|
344
|
+
onClear={() => {
|
|
345
|
+
setSelectedItems([]);
|
|
346
|
+
}}
|
|
347
|
+
/>
|
|
348
|
+
);
|
|
349
|
+
},
|
|
350
|
+
};
|
|
351
|
+
|
|
293
352
|
export const CustomTrigger: Story<Month> = {
|
|
294
353
|
args: {
|
|
295
354
|
placeholder: 'Month',
|
|
@@ -30,6 +30,9 @@ import { useInputAttributes, WithInputAttributesProps } from './contexts';
|
|
|
30
30
|
import { InputGroup } from './InputGroup';
|
|
31
31
|
import { SearchInput } from './SearchInput';
|
|
32
32
|
import messages from './SelectInput.messages';
|
|
33
|
+
import Header from '../header';
|
|
34
|
+
import Section from '../section';
|
|
35
|
+
import { ButtonProps } from '../button/Button.types';
|
|
33
36
|
|
|
34
37
|
const MAX_ITEMS_WITHOUT_VIRTUALIZATION = 50;
|
|
35
38
|
|
|
@@ -62,6 +65,10 @@ export interface SelectInputGroupItem<T = string> {
|
|
|
62
65
|
type: 'group';
|
|
63
66
|
label: string;
|
|
64
67
|
options: readonly SelectInputOptionItem<T>[];
|
|
68
|
+
action?: {
|
|
69
|
+
label: string;
|
|
70
|
+
onClick: ButtonProps['onClick'];
|
|
71
|
+
};
|
|
65
72
|
}
|
|
66
73
|
|
|
67
74
|
export interface SelectInputSeparatorItem {
|
|
@@ -810,23 +817,33 @@ function SelectInputGroupItemView<T = string>({
|
|
|
810
817
|
}: SelectInputGroupItemViewProps<T>) {
|
|
811
818
|
const headerId = useId();
|
|
812
819
|
|
|
820
|
+
const header = (
|
|
821
|
+
<Header
|
|
822
|
+
as="header"
|
|
823
|
+
role="none"
|
|
824
|
+
id={headerId}
|
|
825
|
+
title={item.label}
|
|
826
|
+
// @ts-expect-error when we migrate ActionButton to new Button this should be sorted
|
|
827
|
+
action={
|
|
828
|
+
item.action && {
|
|
829
|
+
text: item.action.label,
|
|
830
|
+
onClick: item.action.onClick,
|
|
831
|
+
}
|
|
832
|
+
}
|
|
833
|
+
className="np-select-input-group-item-header p-x-1"
|
|
834
|
+
/>
|
|
835
|
+
);
|
|
836
|
+
|
|
813
837
|
return (
|
|
814
838
|
// An empty container may be rendered when no options match `needle`
|
|
815
839
|
// However, pre-filtering would result in worse performance overall
|
|
816
|
-
<
|
|
840
|
+
<Section
|
|
841
|
+
as="section"
|
|
817
842
|
role="group"
|
|
818
843
|
aria-labelledby={headerId}
|
|
819
|
-
className={clsx(needle === null && 'np-select-input-group-item--without-needle')}
|
|
844
|
+
className={clsx('m-y-0', needle === null && 'np-select-input-group-item--without-needle')}
|
|
820
845
|
>
|
|
821
|
-
{needle == null ?
|
|
822
|
-
<header
|
|
823
|
-
id={headerId}
|
|
824
|
-
role="none"
|
|
825
|
-
className="np-select-input-group-item-header np-text-title-group"
|
|
826
|
-
>
|
|
827
|
-
{item.label}
|
|
828
|
-
</header>
|
|
829
|
-
) : null}
|
|
846
|
+
{needle == null ? header : null}
|
|
830
847
|
{item.options.map((option, index) => (
|
|
831
848
|
<SelectInputItemView
|
|
832
849
|
// eslint-disable-next-line react/no-array-index-key
|
|
@@ -836,7 +853,7 @@ function SelectInputGroupItemView<T = string>({
|
|
|
836
853
|
needle={needle}
|
|
837
854
|
/>
|
|
838
855
|
))}
|
|
839
|
-
</
|
|
856
|
+
</Section>
|
|
840
857
|
);
|
|
841
858
|
}
|
|
842
859
|
|
package/src/main.css
CHANGED
|
@@ -2943,10 +2943,6 @@ html:not([dir="rtl"]) .np-flow-navigation--sm .np-flow-navigation__stepper {
|
|
|
2943
2943
|
z-index: 10;
|
|
2944
2944
|
background-color: #ffffff;
|
|
2945
2945
|
background-color: var(--color-background-elevated);
|
|
2946
|
-
padding: 8px 16px 4px;
|
|
2947
|
-
padding: var(--size-8) var(--size-16) var(--size-4);
|
|
2948
|
-
color: #5d7079;
|
|
2949
|
-
color: var(--color-content-secondary);
|
|
2950
2946
|
}
|
|
2951
2947
|
.np-select-input-option-container {
|
|
2952
2948
|
display: flex;
|
package/src/section/Section.tsx
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import { clsx } from 'clsx';
|
|
2
|
-
import { PropsWithChildren } from 'react';
|
|
2
|
+
import { HTMLAttributes, PropsWithChildren } from 'react';
|
|
3
3
|
|
|
4
4
|
import { CommonProps } from '../common';
|
|
5
5
|
|
|
6
6
|
type SectionProps = PropsWithChildren<
|
|
7
7
|
CommonProps & {
|
|
8
|
-
as?: 'div' | 'fieldset';
|
|
8
|
+
as?: 'div' | 'fieldset' | 'section';
|
|
9
9
|
withHorizontalPadding?: boolean;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
> &
|
|
12
|
+
Pick<HTMLAttributes<HTMLDivElement>, 'role' | 'aria-labelledby'>;
|
|
12
13
|
|
|
13
14
|
/**
|
|
14
15
|
*
|
|
@@ -20,12 +21,16 @@ const Section = ({
|
|
|
20
21
|
children,
|
|
21
22
|
className,
|
|
22
23
|
withHorizontalPadding = false,
|
|
24
|
+
role = undefined,
|
|
25
|
+
...restProps
|
|
23
26
|
}: SectionProps) => {
|
|
24
27
|
return (
|
|
25
28
|
<Element
|
|
26
29
|
className={clsx('np-section', className, {
|
|
27
30
|
'np-section--with-horizontal-padding': withHorizontalPadding,
|
|
28
31
|
})}
|
|
32
|
+
role={role}
|
|
33
|
+
{...restProps}
|
|
29
34
|
>
|
|
30
35
|
{children}
|
|
31
36
|
</Element>
|
package/src/title/Title.tsx
CHANGED
|
@@ -18,7 +18,7 @@ type Props = LabelHTMLAttributes<HTMLHeadingElement | HTMLSpanElement | HTMLLabe
|
|
|
18
18
|
/**
|
|
19
19
|
* Default value will based one `type` prop
|
|
20
20
|
*/
|
|
21
|
-
as?: 'span' | 'label' | 'li' | 'legend' | Heading;
|
|
21
|
+
as?: 'span' | 'label' | 'li' | 'legend' | 'header' | Heading;
|
|
22
22
|
/**
|
|
23
23
|
* Default value: {@link DEFAULT_TYPE}
|
|
24
24
|
*/
|