@transferwise/components 0.0.0-experimental-335b83d → 0.0.0-experimental-fd2ddc2

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.
Files changed (82) hide show
  1. package/build/index.esm.js +65 -688
  2. package/build/index.esm.js.map +1 -1
  3. package/build/index.js +65 -691
  4. package/build/index.js.map +1 -1
  5. package/build/main.css +1 -1
  6. package/build/styles/inputs/Input.css +1 -1
  7. package/build/styles/inputs/InputGroup.css +1 -1
  8. package/build/styles/inputs/TextArea.css +1 -1
  9. package/build/styles/main.css +1 -1
  10. package/build/styles/promoCard/PromoCard.css +1 -1
  11. package/build/types/common/card/index.d.ts +1 -0
  12. package/build/types/common/card/index.d.ts.map +1 -1
  13. package/build/types/dateLookup/dateTrigger/DateTrigger.messages.d.ts +7 -7
  14. package/build/types/dateLookup/dateTrigger/DateTrigger.messages.d.ts.map +1 -1
  15. package/build/types/index.d.ts +0 -4
  16. package/build/types/index.d.ts.map +1 -1
  17. package/build/types/inputs/Input.d.ts +0 -1
  18. package/build/types/inputs/Input.d.ts.map +1 -1
  19. package/build/types/inputs/_common.d.ts.map +1 -1
  20. package/build/types/promoCard/PromoCard.d.ts +9 -3
  21. package/build/types/promoCard/PromoCard.d.ts.map +1 -1
  22. package/build/types/promoCard/PromoCardIndicator.d.ts +5 -3
  23. package/build/types/promoCard/PromoCardIndicator.d.ts.map +1 -1
  24. package/package.json +22 -28
  25. package/src/common/card/Card.tsx +1 -1
  26. package/src/common/card/index.ts +1 -0
  27. package/src/index.ts +0 -8
  28. package/src/inputs/Input.css +1 -1
  29. package/src/inputs/Input.less +0 -14
  30. package/src/inputs/Input.tsx +2 -6
  31. package/src/inputs/InputGroup.css +1 -1
  32. package/src/inputs/InputGroup.less +1 -6
  33. package/src/inputs/TextArea.css +1 -1
  34. package/src/inputs/TextArea.less +0 -5
  35. package/src/inputs/_common.less +4 -0
  36. package/src/inputs/_common.ts +1 -0
  37. package/src/main.css +1 -1
  38. package/src/main.less +0 -4
  39. package/src/promoCard/PromoCard.css +1 -1
  40. package/src/promoCard/PromoCard.less +9 -9
  41. package/src/promoCard/PromoCard.spec.tsx +1 -0
  42. package/src/promoCard/PromoCard.story.tsx +86 -29
  43. package/src/promoCard/PromoCard.tsx +69 -22
  44. package/src/promoCard/PromoCardIndicator.tsx +20 -8
  45. package/src/select/searchBox/__snapshots__/SearchBox.spec.js.snap +1 -1
  46. package/src/ssr.spec.js +0 -7
  47. package/build/styles/inputs/SelectInput.css +0 -1
  48. package/build/types/common/hooks/useMedia.d.ts +0 -2
  49. package/build/types/common/hooks/useMedia.d.ts.map +0 -1
  50. package/build/types/common/hooks/useScreenSize.d.ts +0 -3
  51. package/build/types/common/hooks/useScreenSize.d.ts.map +0 -1
  52. package/build/types/common/preventScroll/PreventScroll.d.ts +0 -2
  53. package/build/types/common/preventScroll/PreventScroll.d.ts.map +0 -1
  54. package/build/types/inputs/SearchInput.d.ts +0 -10
  55. package/build/types/inputs/SearchInput.d.ts.map +0 -1
  56. package/build/types/inputs/SelectInput.d.ts +0 -41
  57. package/build/types/inputs/SelectInput.d.ts.map +0 -1
  58. package/build/types/inputs/_BottomSheet.d.ts +0 -17
  59. package/build/types/inputs/_BottomSheet.d.ts.map +0 -1
  60. package/build/types/inputs/_ButtonInput.d.ts +0 -6
  61. package/build/types/inputs/_ButtonInput.d.ts.map +0 -1
  62. package/build/types/inputs/_Popover.d.ts +0 -18
  63. package/build/types/inputs/_Popover.d.ts.map +0 -1
  64. package/build/types/utilities/wrapInFragment.d.ts +0 -3
  65. package/build/types/utilities/wrapInFragment.d.ts.map +0 -1
  66. package/src/common/hooks/useMedia.ts +0 -15
  67. package/src/common/hooks/useScreenSize.ts +0 -7
  68. package/src/common/preventScroll/PreventScroll.tsx +0 -6
  69. package/src/inputs/SearchInput.story.tsx +0 -40
  70. package/src/inputs/SearchInput.tsx +0 -35
  71. package/src/inputs/SelectInput.css +0 -1
  72. package/src/inputs/SelectInput.less +0 -183
  73. package/src/inputs/SelectInput.story.tsx +0 -259
  74. package/src/inputs/SelectInput.tsx +0 -565
  75. package/src/inputs/_BottomSheet.less +0 -107
  76. package/src/inputs/_BottomSheet.tsx +0 -128
  77. package/src/inputs/_ButtonInput.less +0 -7
  78. package/src/inputs/_ButtonInput.tsx +0 -27
  79. package/src/inputs/_Popover.less +0 -38
  80. package/src/inputs/_Popover.tsx +0 -118
  81. package/src/utilities/wrapInFragment.tsx +0 -3
  82. /package/src/dateLookup/dateTrigger/{DateTrigger.messages.ts → DateTrigger.messages.js} +0 -0
@@ -1,18 +0,0 @@
1
- /// <reference types="react" />
2
- import { type Side } from '@floating-ui/react';
3
- export interface PopoverProps {
4
- placement?: Side;
5
- open: boolean;
6
- renderTrigger: (args: {
7
- ref: React.RefCallback<Element>;
8
- getInteractionProps: (customEventHandlers?: React.HTMLProps<Element>) => {
9
- [key: string]: unknown;
10
- };
11
- }) => React.ReactNode;
12
- title?: string;
13
- padding?: 'none' | 'md';
14
- children?: React.ReactNode;
15
- onClose?: () => void;
16
- }
17
- export declare function Popover({ placement, open, renderTrigger, title, padding, children, onClose, }: PopoverProps): import("react").JSX.Element;
18
- //# sourceMappingURL=_Popover.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_Popover.d.ts","sourceRoot":"","sources":["../../../src/inputs/_Popover.tsx"],"names":[],"mappings":";AAAA,OAAO,EAOL,KAAK,IAAI,EAMV,MAAM,oBAAoB,CAAC;AAO5B,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,IAAI,EAAE,OAAO,CAAC;IACd,aAAa,EAAE,CAAC,IAAI,EAAE;QACpB,GAAG,EAAE,KAAK,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAChC,mBAAmB,EAAE,CAAC,mBAAmB,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK;YACvE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;SACxB,CAAC;KACH,KAAK,KAAK,CAAC,SAAS,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC3B,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;CACtB;AAID,wBAAgB,OAAO,CAAC,EACtB,SAAS,EACT,IAAI,EACJ,aAAa,EACb,KAAK,EACL,OAAc,EACd,QAAQ,EACR,OAAO,GACR,EAAE,YAAY,+BAwEd"}
@@ -1,3 +0,0 @@
1
- /// <reference types="react" />
2
- export declare function wrapInFragment(value: unknown): import("react").JSX.Element;
3
- //# sourceMappingURL=wrapInFragment.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"wrapInFragment.d.ts","sourceRoot":"","sources":["../../../src/utilities/wrapInFragment.tsx"],"names":[],"mappings":";AAAA,wBAAgB,cAAc,CAAC,KAAK,EAAE,OAAO,+BAE5C"}
@@ -1,15 +0,0 @@
1
- import { useSyncExternalStore } from 'use-sync-external-store/shim';
2
-
3
- export function useMedia(query: string) {
4
- return useSyncExternalStore(
5
- (onStoreChange) => {
6
- const mediaQueryList = window.matchMedia(query);
7
- mediaQueryList.addEventListener('change', onStoreChange);
8
- return () => {
9
- mediaQueryList.removeEventListener('change', onStoreChange);
10
- };
11
- },
12
- () => (typeof window !== 'undefined' ? window.matchMedia(query).matches : undefined),
13
- () => undefined,
14
- );
15
- }
@@ -1,7 +0,0 @@
1
- import { Breakpoint } from '../propsValues/breakpoint';
2
-
3
- import { useMedia } from './useMedia';
4
-
5
- export function useScreenSize(size: Breakpoint) {
6
- return useMedia(`(min-width: ${size}px)`);
7
- }
@@ -1,6 +0,0 @@
1
- import { usePreventScroll } from '@react-aria/overlays';
2
-
3
- export function PreventScroll() {
4
- usePreventScroll();
5
- return null;
6
- }
@@ -1,40 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react';
2
- import { useState } from 'react';
3
-
4
- import { SearchInput } from './SearchInput';
5
-
6
- export default {
7
- component: SearchInput,
8
- title: 'Forms/SearchInput',
9
- } satisfies Meta<typeof SearchInput>;
10
-
11
- type Story = StoryObj<typeof SearchInput>;
12
-
13
- export const Basic: Story = {
14
- render: (args) => <SearchInputBasic {...args} />,
15
- args: {
16
- size: 'md',
17
- shape: 'pill',
18
- disabled: false,
19
- },
20
- argTypes: {
21
- onChange: {
22
- action: 'changed',
23
- },
24
- },
25
- };
26
-
27
- function SearchInputBasic({ onChange, ...restProps }: NonNullable<Story['args']>) {
28
- const [value, setValue] = useState('Text value');
29
-
30
- return (
31
- <SearchInput
32
- {...restProps}
33
- value={value}
34
- onChange={(event) => {
35
- setValue(event.currentTarget.value);
36
- onChange?.(event);
37
- }}
38
- />
39
- );
40
- }
@@ -1,35 +0,0 @@
1
- import { Search } from '@transferwise/icons';
2
- import { forwardRef } from 'react';
3
-
4
- import { Merge } from '../utils';
5
-
6
- import { Input } from './Input';
7
- import { InputGroup } from './InputGroup';
8
-
9
- export interface SearchInputProps
10
- extends Merge<
11
- React.ComponentPropsWithRef<'input'>,
12
- {
13
- size?: 'sm' | 'md';
14
- shape?: 'rectangle' | 'pill';
15
- 'aria-invalid'?: boolean;
16
- }
17
- > {}
18
-
19
- export const SearchInput = forwardRef(function SearchInput(
20
- { shape = 'pill', disabled, className, ...restProps }: SearchInputProps,
21
- ref: React.ForwardedRef<HTMLInputElement>,
22
- ) {
23
- return (
24
- <InputGroup
25
- addonStart={{
26
- content: <Search size={24} />,
27
- initialContentWidth: 24,
28
- }}
29
- disabled={disabled}
30
- className={className}
31
- >
32
- <Input ref={ref} role="searchbox" inputMode="search" shape={shape} {...restProps} />
33
- </InputGroup>
34
- );
35
- });
@@ -1 +0,0 @@
1
- .np-select-input-placeholder{color:#768e9c;color:var(--color-content-tertiary);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.np-select-input-options-container{display:flex;flex-direction:column;height:100%}.np-select-input-options-container:focus{outline:none}@media (min-width:576px){.np-select-input-options-container{max-height:28rem}}.np-select-input-query-container{display:flex;flex-direction:column;padding:8px;padding:var(--size-8);padding-top:0}@media (min-width:576px){.np-select-input-query-container{padding-top:8px;padding-top:var(--size-8)}}.np-select-input-listbox-container{height:var(--initial-height);overflow-y:auto;position:relative;scroll-padding-bottom:8px;scroll-padding-bottom:var(--size-8);scroll-padding-top:8px;scroll-padding-top:var(--size-8)}@media (min-width:576px){.np-select-input-listbox-container{height:auto}}.np-select-input-listbox-container--has-group{scroll-padding-top:32px;scroll-padding-top:var(--size-32)}.np-select-input-listbox{padding:8px;padding:var(--size-8)}.np-select-input-listbox:focus{outline:none}.np-select-input-separator-item{border-top-width:1px;margin:8px;margin:var(--size-8)}.np-select-input-group-item--without-needle:first-child{margin-top:-8px;margin-top:calc(var(--size-8)*-1)}.np-select-input-group-item-header{background-color:#fff;background-color:var(--color-background-elevated);color:#5d7079;color:var(--color-content-secondary);padding:8px 16px 4px;padding:var(--size-8) var(--size-16) var(--size-4);position:sticky;top:0;z-index:10}.np-select-input-option-container{align-items:center;border-radius:10px;border-radius:var(--radius-small);color:#37517e;color:var(--color-content-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex;padding:12px 16px;padding:var(--size-12) var(--size-16)}.np-select-input-option-container--active{background-color:var(--color-background-screen-hover)}.np-select-input-option-container--disabled{opacity:.45}.np-select-input-option-check--not-selected{visibility:hidden}.np-select-input-option{flex:1}.np-select-input-option-content-container{align-items:center;color:#37517e;color:var(--color-content-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex}.np-select-input-option-content-icon{display:flex}.np-select-input-option-content-icon--not-compact{align-self:flex-start}.np-select-input-option-content-text{display:flex;flex:1;flex-direction:column;overflow:hidden}.np-select-input-option-content-text-secondary{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-option-content-text-compact{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.np-select-input-option-content-text-line-1>:not([hidden])~:not([hidden]){margin-left:8px;margin-left:var(--size-8);margin-right:8px;margin-right:var(--size-8)}.np-select-input-addon-container{align-items:center;display:inline-flex;pointer-events:none}.np-select-input-addon{align-items:center;background:none;border-radius:.125rem;border-width:0;display:inline-flex;height:32px;height:var(--size-32);justify-content:center;width:32px;width:var(--size-32)}.np-select-input-addon--interactive{color:#c9cbce;color:var(--color-interactive-secondary);pointer-events:auto}.np-select-input-addon--interactive:hover{color:#b5b7ba;color:var(--color-interactive-secondary-hover)}.np-select-input-addon--interactive:focus{outline:none}.np-select-input-addon--interactive:focus-visible{outline:var(--ring-outline-color) solid var(--ring-outline-width);outline-offset:var(--ring-outline-offset)}.np-select-input-addon-separator{border-inline-start-width:1px;height:24px;height:var(--size-24)}
@@ -1,183 +0,0 @@
1
- @import (reference) "../../node_modules/@transferwise/neptune-css/src/less/ring.less";
2
-
3
- .np-select-input-placeholder {
4
- overflow: hidden;
5
- text-overflow: ellipsis;
6
- white-space: nowrap;
7
- color: var(--color-content-tertiary);
8
- }
9
-
10
- .np-select-input-options-container {
11
- display: flex;
12
- height: 100%;
13
- flex-direction: column;
14
-
15
- &:focus {
16
- outline: none;
17
- }
18
-
19
- @media (--screen-sm) {
20
- & {
21
- max-height: 28rem /* 448px */;
22
- }
23
- }
24
- }
25
-
26
- .np-select-input-query-container {
27
- display: flex;
28
- flex-direction: column;
29
- padding: var(--size-8);
30
- padding-top: 0px;
31
-
32
- @media (--screen-sm) {
33
- & {
34
- padding-top: var(--size-8);
35
- }
36
- }
37
- }
38
-
39
- .np-select-input-listbox-container {
40
- position: relative;
41
- height: var(--initial-height);
42
- scroll-padding-top: var(--size-8);
43
- scroll-padding-bottom: var(--size-8);
44
- overflow-y: auto;
45
-
46
- @media (--screen-sm) {
47
- & {
48
- height: auto;
49
- }
50
- }
51
-
52
- &--has-group {
53
- scroll-padding-top: var(--size-32);
54
- }
55
- }
56
-
57
- .np-select-input-listbox {
58
- padding: var(--size-8);
59
-
60
- &:focus {
61
- outline: none;
62
- }
63
- }
64
-
65
- .np-select-input-separator-item {
66
- margin: var(--size-8);
67
- border-top-width: 1px;
68
- }
69
-
70
- .np-select-input-group-item {
71
- &--without-needle:first-child {
72
- margin-top: calc(-1 * var(--size-8));
73
- }
74
- }
75
-
76
- .np-select-input-group-item-header {
77
- position: sticky;
78
- top: 0px;
79
- z-index: 10;
80
- background-color: var(--color-background-elevated);
81
- padding: var(--size-8) var(--size-16) var(--size-4);
82
- color: var(--color-content-secondary);
83
- }
84
-
85
- .np-select-input-option-container {
86
- display: flex;
87
- align-items: center;
88
- column-gap: var(--size-8);
89
- border-radius: var(--radius-small);
90
- padding: var(--size-12) var(--size-16);
91
- color: var(--color-content-primary);
92
-
93
- &--active {
94
- background-color: var(--color-background-screen-hover);
95
- }
96
-
97
- &--disabled {
98
- opacity: 0.45;
99
- }
100
- }
101
-
102
- .np-select-input-option-check {
103
- &--not-selected {
104
- visibility: hidden;
105
- }
106
- }
107
-
108
- .np-select-input-option {
109
- flex: 1;
110
- }
111
-
112
- .np-select-input-option-content-container {
113
- display: flex;
114
- align-items: center;
115
- column-gap: var(--size-8);
116
- color: var(--color-content-primary);
117
- }
118
-
119
- .np-select-input-option-content-icon {
120
- display: flex;
121
-
122
- &--not-compact {
123
- align-self: flex-start;
124
- }
125
- }
126
-
127
- .np-select-input-option-content-text {
128
- display: flex;
129
- flex: 1;
130
- flex-direction: column;
131
- overflow: hidden;
132
- }
133
-
134
- .np-select-input-option-content-text-secondary {
135
- color: var(--color-content-secondary);
136
- }
137
-
138
- .np-select-input-option-content-text-compact {
139
- overflow: hidden;
140
- text-overflow: ellipsis;
141
- white-space: nowrap;
142
- }
143
-
144
- .np-select-input-option-content-text-line-1 {
145
- > :not([hidden]) ~ :not([hidden]) {
146
- margin-right: var(--size-8);
147
- margin-left: var(--size-8);
148
- }
149
- }
150
-
151
- .np-select-input-addon-container {
152
- pointer-events: none;
153
- display: inline-flex;
154
- align-items: center;
155
- }
156
-
157
- .np-select-input-addon {
158
- border-width: 0;
159
- background: none;
160
-
161
- display: inline-flex;
162
- height: var(--size-32);
163
- width: var(--size-32);
164
- align-items: center;
165
- justify-content: center;
166
- border-radius: 0.125rem /* 2px */; /* TODO: Tokenize */
167
-
168
- &--interactive {
169
- pointer-events: auto;
170
- color: var(--color-interactive-secondary);
171
-
172
- &:hover {
173
- color: var(--color-interactive-secondary-hover);
174
- }
175
-
176
- .focus-ring();
177
- }
178
- }
179
-
180
- .np-select-input-addon-separator {
181
- height: var(--size-24);
182
- border-inline-start-width: 1px;
183
- }
@@ -1,259 +0,0 @@
1
- import { Meta, StoryObj } from '@storybook/react';
2
- import { Calendar } from '@transferwise/icons';
3
- import { Flag } from '@wise/art';
4
- import { useState } from 'react';
5
-
6
- import { getMonthNames } from '../common/dateUtils';
7
-
8
- import { SelectInput, type SelectInputItem, SelectInputOptionContent } from './SelectInput';
9
-
10
- export default {
11
- component: SelectInput,
12
- } satisfies Meta<typeof SelectInput>;
13
-
14
- interface TestMonth {
15
- id: number;
16
- name: string;
17
- unavailable: boolean;
18
- }
19
-
20
- const testMonths: TestMonth[] = getMonthNames('en-US').map((name, index) => ({
21
- id: index + 1,
22
- name,
23
- unavailable: index % 6 === 2,
24
- }));
25
-
26
- const testQuarters = [
27
- testMonths.slice(0, 3),
28
- testMonths.slice(3, 6),
29
- testMonths.slice(6, 9),
30
- testMonths.slice(9, 12),
31
- ] as const;
32
-
33
- export const Basic: StoryObj<{
34
- filterable: boolean;
35
- filterPlaceholder: string;
36
- clearable: boolean;
37
- invalid: boolean;
38
- disabled: boolean;
39
- onChange: (value: TestMonth | null) => void;
40
- onClear: () => void;
41
- }> = {
42
- render: function Story({
43
- filterable,
44
- filterPlaceholder,
45
- clearable,
46
- disabled,
47
- onChange,
48
- onClear,
49
- }) {
50
- const [selectedMonth, setSelectedMonth] = useState<TestMonth | null>(null);
51
-
52
- return (
53
- <div className="d-flex flex-column">
54
- {/* TODO:
55
- <Field
56
- label="Label"
57
- hint="Information message."
58
- error={invalid ? "Error message." : undefined}
59
- >
60
- */}
61
- <SelectInput
62
- placeholder="Month"
63
- items={testQuarters
64
- .flatMap<SelectInputItem<TestMonth>>((quarterMonths, index) => [
65
- {
66
- type: 'group',
67
- label: `Quarter #${index + 1}`,
68
- options: quarterMonths.map((month) => ({
69
- type: 'option',
70
- value: month,
71
- filterMatchers: [month.name],
72
- disabled: month.unavailable,
73
- })),
74
- },
75
- { type: 'separator' },
76
- ])
77
- .slice(0, -1)}
78
- value={selectedMonth}
79
- renderValue={(month, compact) => (
80
- <SelectInputOptionContent
81
- title={month.name}
82
- note="Note"
83
- description={compact ? undefined : `Month #${month.id}`}
84
- icon={<Calendar size={24} />}
85
- />
86
- )}
87
- filterable={filterable}
88
- filterPlaceholder={filterPlaceholder}
89
- disabled={disabled}
90
- onChange={(month) => {
91
- setSelectedMonth(month);
92
- onChange(month);
93
- }}
94
- onClear={
95
- clearable
96
- ? () => {
97
- setSelectedMonth(null);
98
- onClear();
99
- }
100
- : undefined
101
- }
102
- />
103
- </div>
104
- );
105
- },
106
- args: {
107
- filterable: true,
108
- filterPlaceholder: 'Type a month’s name',
109
- clearable: true,
110
- invalid: false,
111
- disabled: false,
112
- },
113
- argTypes: {
114
- onChange: {
115
- action: 'changed',
116
- },
117
- onClear: {
118
- action: 'cleared',
119
- },
120
- },
121
- };
122
-
123
- interface Month {
124
- id: number;
125
- name: string;
126
- }
127
-
128
- const months: Month[] = getMonthNames('en-US').map((name, index) => ({
129
- id: index + 1,
130
- name,
131
- }));
132
-
133
- export const Months: StoryObj<{
134
- onChange: (value: Month | null) => void;
135
- onClear: () => void;
136
- }> = {
137
- render: function Story({ onChange, onClear }) {
138
- const [selectedMonth, setSelectedMonth] = useState<Month | null>(null);
139
-
140
- return (
141
- <div className="d-flex flex-column">
142
- <SelectInput
143
- placeholder="Month"
144
- items={months.map((month) => ({ type: 'option', value: month }))}
145
- value={selectedMonth}
146
- renderValue={(month) => <SelectInputOptionContent title={month.name} />}
147
- onChange={(month) => {
148
- setSelectedMonth(month);
149
- onChange(month);
150
- }}
151
- onClear={() => {
152
- setSelectedMonth(null);
153
- onClear();
154
- }}
155
- />
156
- </div>
157
- );
158
- },
159
- argTypes: {
160
- onChange: {
161
- action: 'changed',
162
- },
163
- onClear: {
164
- action: 'cleared',
165
- },
166
- },
167
- };
168
-
169
- interface Currency {
170
- code: string;
171
- name: string;
172
- countries?: string[];
173
- }
174
-
175
- const popularCurrencies: Currency[] = [
176
- {
177
- code: 'USD',
178
- name: 'United States dollar',
179
- countries: ['Hong Kong', 'Saudi Arabia'],
180
- },
181
- {
182
- code: 'EUR',
183
- name: 'Euro',
184
- countries: ['Spain', 'Germany', 'France', 'Austria', 'Estonia'],
185
- },
186
- {
187
- code: 'GBP',
188
- name: 'British pound',
189
- countries: ['England', 'Scotland', 'Wales'],
190
- },
191
- ];
192
-
193
- const otherCurrencies: Currency[] = [
194
- {
195
- code: 'CAD',
196
- name: 'Canadian dollar',
197
- countries: ['Canada'],
198
- },
199
- {
200
- code: 'AUD',
201
- name: 'Australian dollar',
202
- },
203
- ];
204
-
205
- const allCurrencies: Currency[] = [...popularCurrencies, ...otherCurrencies].sort((a, b) =>
206
- a.code.localeCompare(b.code),
207
- );
208
-
209
- export const Currencies: StoryObj<{
210
- onChange: (value: Currency) => void;
211
- }> = {
212
- render: function Story({ onChange }) {
213
- const [selectedCurrency, setSelectedCurrency] = useState<Currency>(popularCurrencies[0]);
214
-
215
- return (
216
- <div className="d-flex flex-column">
217
- <SelectInput
218
- items={[
219
- {
220
- type: 'group',
221
- label: 'Popular currencies',
222
- options: popularCurrencies.map((currency) => ({
223
- type: 'option',
224
- value: currency,
225
- })),
226
- },
227
- {
228
- type: 'group',
229
- label: 'All currencies',
230
- options: allCurrencies.map((currency) => ({
231
- type: 'option',
232
- value: currency,
233
- })),
234
- },
235
- ]}
236
- value={selectedCurrency}
237
- renderValue={(currency) => (
238
- <SelectInputOptionContent
239
- title={currency.code}
240
- note={currency.name}
241
- icon={<Flag code={currency.code} intrinsicSize={24} />}
242
- />
243
- )}
244
- filterable
245
- filterPlaceholder="Type a currency / country"
246
- onChange={(currency) => {
247
- setSelectedCurrency(currency);
248
- onChange(currency);
249
- }}
250
- />
251
- </div>
252
- );
253
- },
254
- argTypes: {
255
- onChange: {
256
- action: 'changed',
257
- },
258
- },
259
- };