@transferwise/components 46.98.0 → 46.98.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.
Files changed (199) hide show
  1. package/build/dateInput/DateInput.js +4 -4
  2. package/build/dateInput/DateInput.js.map +1 -1
  3. package/build/dateInput/DateInput.mjs +4 -4
  4. package/build/dateInput/DateInput.mjs.map +1 -1
  5. package/build/dateLookup/DateLookup.js +4 -4
  6. package/build/dateLookup/DateLookup.js.map +1 -1
  7. package/build/dateLookup/DateLookup.mjs +4 -4
  8. package/build/dateLookup/DateLookup.mjs.map +1 -1
  9. package/build/dateLookup/dayCalendar/table/DayCalendarTable.js +3 -3
  10. package/build/dateLookup/dayCalendar/table/DayCalendarTable.js.map +1 -1
  11. package/build/dateLookup/dayCalendar/table/DayCalendarTable.mjs +3 -3
  12. package/build/dateLookup/dayCalendar/table/DayCalendarTable.mjs.map +1 -1
  13. package/build/i18n/cs.json +0 -2
  14. package/build/i18n/cs.json.js +0 -2
  15. package/build/i18n/cs.json.js.map +1 -1
  16. package/build/i18n/cs.json.mjs +0 -2
  17. package/build/i18n/cs.json.mjs.map +1 -1
  18. package/build/i18n/de.json +0 -2
  19. package/build/i18n/de.json.js +0 -2
  20. package/build/i18n/de.json.js.map +1 -1
  21. package/build/i18n/de.json.mjs +0 -2
  22. package/build/i18n/de.json.mjs.map +1 -1
  23. package/build/i18n/en.json +0 -2
  24. package/build/i18n/en.json.js +0 -2
  25. package/build/i18n/en.json.js.map +1 -1
  26. package/build/i18n/en.json.mjs +0 -2
  27. package/build/i18n/en.json.mjs.map +1 -1
  28. package/build/i18n/es.json +0 -2
  29. package/build/i18n/es.json.js +0 -2
  30. package/build/i18n/es.json.js.map +1 -1
  31. package/build/i18n/es.json.mjs +0 -2
  32. package/build/i18n/es.json.mjs.map +1 -1
  33. package/build/i18n/fr.json +0 -2
  34. package/build/i18n/fr.json.js +0 -2
  35. package/build/i18n/fr.json.js.map +1 -1
  36. package/build/i18n/fr.json.mjs +0 -2
  37. package/build/i18n/fr.json.mjs.map +1 -1
  38. package/build/i18n/hu.json +0 -2
  39. package/build/i18n/hu.json.js +0 -2
  40. package/build/i18n/hu.json.js.map +1 -1
  41. package/build/i18n/hu.json.mjs +0 -2
  42. package/build/i18n/hu.json.mjs.map +1 -1
  43. package/build/i18n/id.json +0 -2
  44. package/build/i18n/id.json.js +0 -2
  45. package/build/i18n/id.json.js.map +1 -1
  46. package/build/i18n/id.json.mjs +0 -2
  47. package/build/i18n/id.json.mjs.map +1 -1
  48. package/build/i18n/it.json +0 -2
  49. package/build/i18n/it.json.js +0 -2
  50. package/build/i18n/it.json.js.map +1 -1
  51. package/build/i18n/it.json.mjs +0 -2
  52. package/build/i18n/it.json.mjs.map +1 -1
  53. package/build/i18n/ja.json +0 -2
  54. package/build/i18n/ja.json.js +0 -2
  55. package/build/i18n/ja.json.js.map +1 -1
  56. package/build/i18n/ja.json.mjs +0 -2
  57. package/build/i18n/ja.json.mjs.map +1 -1
  58. package/build/i18n/nl.json +0 -2
  59. package/build/i18n/pl.json +0 -2
  60. package/build/i18n/pl.json.js +0 -2
  61. package/build/i18n/pl.json.js.map +1 -1
  62. package/build/i18n/pl.json.mjs +0 -2
  63. package/build/i18n/pl.json.mjs.map +1 -1
  64. package/build/i18n/pt.json +0 -2
  65. package/build/i18n/pt.json.js +0 -2
  66. package/build/i18n/pt.json.js.map +1 -1
  67. package/build/i18n/pt.json.mjs +0 -2
  68. package/build/i18n/pt.json.mjs.map +1 -1
  69. package/build/i18n/ro.json +0 -2
  70. package/build/i18n/ro.json.js +0 -2
  71. package/build/i18n/ro.json.js.map +1 -1
  72. package/build/i18n/ro.json.mjs +0 -2
  73. package/build/i18n/ro.json.mjs.map +1 -1
  74. package/build/i18n/ru.json +0 -2
  75. package/build/i18n/ru.json.js +0 -2
  76. package/build/i18n/ru.json.js.map +1 -1
  77. package/build/i18n/ru.json.mjs +0 -2
  78. package/build/i18n/ru.json.mjs.map +1 -1
  79. package/build/i18n/th.json +0 -2
  80. package/build/i18n/th.json.js +0 -2
  81. package/build/i18n/th.json.js.map +1 -1
  82. package/build/i18n/th.json.mjs +0 -2
  83. package/build/i18n/th.json.mjs.map +1 -1
  84. package/build/i18n/tr.json +0 -2
  85. package/build/i18n/tr.json.js +0 -2
  86. package/build/i18n/tr.json.js.map +1 -1
  87. package/build/i18n/tr.json.mjs +0 -2
  88. package/build/i18n/tr.json.mjs.map +1 -1
  89. package/build/i18n/zh-CN.json +0 -2
  90. package/build/i18n/zh-CN.json.js +0 -2
  91. package/build/i18n/zh-CN.json.js.map +1 -1
  92. package/build/i18n/zh-CN.json.mjs +0 -2
  93. package/build/i18n/zh-CN.json.mjs.map +1 -1
  94. package/build/i18n/zh-HK.json +0 -2
  95. package/build/i18n/zh-HK.json.js +0 -2
  96. package/build/i18n/zh-HK.json.js.map +1 -1
  97. package/build/i18n/zh-HK.json.mjs +0 -2
  98. package/build/i18n/zh-HK.json.mjs.map +1 -1
  99. package/build/index.js +0 -2
  100. package/build/index.js.map +1 -1
  101. package/build/index.mjs +0 -1
  102. package/build/index.mjs.map +1 -1
  103. package/build/main.css +13 -45
  104. package/build/moneyInput/MoneyInput.js +2 -2
  105. package/build/moneyInput/MoneyInput.js.map +1 -1
  106. package/build/moneyInput/MoneyInput.mjs +2 -2
  107. package/build/moneyInput/MoneyInput.mjs.map +1 -1
  108. package/build/snackbar/Snackbar.js +1 -1
  109. package/build/snackbar/Snackbar.js.map +1 -1
  110. package/build/snackbar/Snackbar.mjs +1 -1
  111. package/build/snackbar/Snackbar.mjs.map +1 -1
  112. package/build/styles/dateInput/DateInput.css +13 -1
  113. package/build/styles/main.css +13 -45
  114. package/build/tabs/Tabs.js +3 -3
  115. package/build/tabs/Tabs.js.map +1 -1
  116. package/build/tabs/Tabs.mjs +3 -3
  117. package/build/tabs/Tabs.mjs.map +1 -1
  118. package/build/test-utils/assets/apple-pay-logo.svg +84 -0
  119. package/build/typeahead/Typeahead.js +2 -2
  120. package/build/typeahead/Typeahead.js.map +1 -1
  121. package/build/typeahead/Typeahead.mjs +2 -2
  122. package/build/typeahead/Typeahead.mjs.map +1 -1
  123. package/build/typeahead/typeaheadInput/TypeaheadInput.js +2 -2
  124. package/build/typeahead/typeaheadInput/TypeaheadInput.js.map +1 -1
  125. package/build/typeahead/typeaheadInput/TypeaheadInput.mjs +2 -2
  126. package/build/typeahead/typeaheadInput/TypeaheadInput.mjs.map +1 -1
  127. package/build/types/index.d.ts +0 -2
  128. package/build/types/index.d.ts.map +1 -1
  129. package/build/types/test-utils/fake-data.d.ts +2 -0
  130. package/build/types/test-utils/fake-data.d.ts.map +1 -1
  131. package/build/types/test-utils/index.d.ts +0 -4
  132. package/build/types/test-utils/index.d.ts.map +1 -1
  133. package/build/types/uploadInput/UploadInput.d.ts.map +1 -1
  134. package/build/upload/Upload.js +2 -2
  135. package/build/upload/Upload.js.map +1 -1
  136. package/build/upload/Upload.mjs +2 -2
  137. package/build/upload/Upload.mjs.map +1 -1
  138. package/build/upload/steps/uploadImageStep/uploadImageStep.js +1 -1
  139. package/build/upload/steps/uploadImageStep/uploadImageStep.js.map +1 -1
  140. package/build/upload/steps/uploadImageStep/uploadImageStep.mjs +1 -1
  141. package/build/upload/steps/uploadImageStep/uploadImageStep.mjs.map +1 -1
  142. package/build/uploadInput/UploadInput.js +0 -1
  143. package/build/uploadInput/UploadInput.js.map +1 -1
  144. package/build/uploadInput/UploadInput.mjs +0 -1
  145. package/build/uploadInput/UploadInput.mjs.map +1 -1
  146. package/package.json +11 -11
  147. package/src/dateInput/DateInput.css +13 -1
  148. package/src/dateInput/DateInput.less +20 -3
  149. package/src/dateInput/DateInput.tests.story.tsx +14 -3
  150. package/src/dateInput/DateInput.tsx +4 -4
  151. package/src/i18n/cs.json +0 -2
  152. package/src/i18n/de.json +0 -2
  153. package/src/i18n/en.json +0 -2
  154. package/src/i18n/es.json +0 -2
  155. package/src/i18n/fr.json +0 -2
  156. package/src/i18n/hu.json +0 -2
  157. package/src/i18n/id.json +0 -2
  158. package/src/i18n/it.json +0 -2
  159. package/src/i18n/ja.json +0 -2
  160. package/src/i18n/nl.json +0 -2
  161. package/src/i18n/pl.json +0 -2
  162. package/src/i18n/pt.json +0 -2
  163. package/src/i18n/ro.json +0 -2
  164. package/src/i18n/ru.json +0 -2
  165. package/src/i18n/th.json +0 -2
  166. package/src/i18n/tr.json +0 -2
  167. package/src/i18n/zh-CN.json +0 -2
  168. package/src/i18n/zh-HK.json +0 -2
  169. package/src/index.ts +0 -2
  170. package/src/legacylistItem/LegacyListItem.story.tsx +5 -5
  171. package/src/legacylistItem/LegacyListItem.tests.story.tsx +6 -6
  172. package/src/main.css +13 -45
  173. package/src/main.less +0 -1
  174. package/src/ssr.spec.tsx +0 -1
  175. package/src/test-utils/assets/apple-pay-logo.svg +84 -0
  176. package/src/test-utils/fake-data.ts +5 -0
  177. package/src/uploadInput/UploadInput.tsx +4 -13
  178. package/build/selectOption/SelectOption.js +0 -131
  179. package/build/selectOption/SelectOption.js.map +0 -1
  180. package/build/selectOption/SelectOption.messages.js +0 -17
  181. package/build/selectOption/SelectOption.messages.js.map +0 -1
  182. package/build/selectOption/SelectOption.messages.mjs +0 -13
  183. package/build/selectOption/SelectOption.messages.mjs.map +0 -1
  184. package/build/selectOption/SelectOption.mjs +0 -127
  185. package/build/selectOption/SelectOption.mjs.map +0 -1
  186. package/build/styles/selectOption/SelectOption.css +0 -44
  187. package/build/types/selectOption/SelectOption.d.ts +0 -21
  188. package/build/types/selectOption/SelectOption.d.ts.map +0 -1
  189. package/build/types/selectOption/SelectOption.messages.d.ts +0 -12
  190. package/build/types/selectOption/SelectOption.messages.d.ts.map +0 -1
  191. package/build/types/selectOption/index.d.ts +0 -3
  192. package/build/types/selectOption/index.d.ts.map +0 -1
  193. package/src/selectOption/SelectOption.css +0 -44
  194. package/src/selectOption/SelectOption.less +0 -40
  195. package/src/selectOption/SelectOption.messages.ts +0 -12
  196. package/src/selectOption/SelectOption.spec.tsx +0 -83
  197. package/src/selectOption/SelectOption.story.tsx +0 -277
  198. package/src/selectOption/SelectOption.tsx +0 -151
  199. package/src/selectOption/index.ts +0 -2
@@ -1,83 +0,0 @@
1
- import { render, userEvent, screen, within, mockMatchMedia } from '../test-utils';
2
- import { composeStories } from '@storybook/react';
3
- import * as stories from './SelectOption.story';
4
- import { Breakpoint } from '../common';
5
- import { wait } from '../test-utils/wait';
6
-
7
- const { Basic: SelectOptionExample } = composeStories(stories);
8
-
9
- mockMatchMedia();
10
-
11
- describe('Select Option', () => {
12
- it('opens dropdown on desktop view', async () => {
13
- render(<SelectOptionExample />);
14
-
15
- let dialog = screen.queryByRole('dialog');
16
- expect(dialog).not.toBeInTheDocument();
17
-
18
- const button = screen.getByRole('button');
19
-
20
- await userEvent.click(button);
21
-
22
- dialog = screen.queryByRole('dialog');
23
- expect(dialog).toBeInTheDocument();
24
- });
25
-
26
- it('opens bottom sheet on mobile view', async () => {
27
- // mock mobile view
28
- window.innerWidth = Breakpoint.EXTRA_SMALL;
29
-
30
- render(<SelectOptionExample />);
31
-
32
- let dialog = screen.queryByRole('dialog');
33
- expect(dialog).not.toBeInTheDocument();
34
-
35
- const button = screen.getByRole('button');
36
-
37
- await userEvent.click(button);
38
-
39
- dialog = screen.queryByRole('dialog');
40
- expect(dialog).toBeInTheDocument();
41
- });
42
-
43
- it('shows options', async () => {
44
- render(<SelectOptionExample />);
45
-
46
- const button = screen.getByRole('button');
47
-
48
- await userEvent.click(button);
49
-
50
- const dialog = screen.getByRole('dialog');
51
- const sectionHeaders = within(dialog).getAllByRole('heading', { name: /balances|jars/i });
52
- expect(sectionHeaders).toHaveLength(2);
53
-
54
- const options = within(dialog).getAllByRole('heading', { level: 4 });
55
- expect(options).toHaveLength(5);
56
- });
57
-
58
- it('choose option', async () => {
59
- // mock mobile view
60
- window.innerWidth = Breakpoint.EXTRA_SMALL;
61
-
62
- render(
63
- <SelectOptionExample placeholder={{ title: 'Please choose balance', actionLabel: 'Pick' }} />,
64
- );
65
-
66
- const button = screen.getByRole('button');
67
-
68
- expect(button).toHaveTextContent('Pick');
69
- expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
70
- await userEvent.click(button);
71
- expect(screen.getByRole('dialog')).toBeInTheDocument();
72
-
73
- const pickedOption = within(screen.getByRole('dialog')).getByText('Trip to Mars');
74
-
75
- await userEvent.click(pickedOption);
76
-
77
- // wait for dialog to close
78
- await wait(500);
79
- expect(screen.getByText('Trip to Mars')).toBeInTheDocument();
80
- expect(screen.queryAllByTestId('chevron-down-icon')).toHaveLength(1);
81
- expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
82
- });
83
- });
@@ -1,277 +0,0 @@
1
- import type { StoryObj } from '@storybook/react';
2
- import { Flag } from '@wise/art';
3
- import SelectOption, {
4
- SelectOptionProps,
5
- SelectOptionValue,
6
- SelectOptiopsSection,
7
- } from './SelectOption';
8
- import { Bank, BankTransfer, Beach, Briefcase, Card, Plane } from '@transferwise/icons';
9
- import { Field } from '../field/Field';
10
- import { lorem10 } from '../test-utils';
11
- import Badge from '../badge';
12
- import Avatar from '../avatar';
13
- import { Sentiment } from '../common';
14
- import { useState } from 'react';
15
-
16
- export default {
17
- title: 'Option/SelectOption',
18
- tags: ['autodocs'],
19
- };
20
-
21
- type Story = StoryObj<typeof SelectOption>;
22
-
23
- type CustomData = { data?: string };
24
-
25
- function cardPaymentMethod(index?: number): SelectOptionValue<CustomData> {
26
- return {
27
- media: <Card />,
28
- title: `Credit card ${index}`,
29
- content: (
30
- <>
31
- <div>Transfer the money to Wise using your bank account.</div>
32
- <div>0.32 GBP in fees, should arrive in seconds</div>
33
- </>
34
- ),
35
- };
36
- }
37
-
38
- const recentPaymentMethods: SelectOptionValue<CustomData>[] = [
39
- cardPaymentMethod(1),
40
- cardPaymentMethod(2),
41
- ];
42
-
43
- const allOtherPaymentMethods: SelectOptionValue<CustomData>[] = [
44
- {
45
- media: <Flag code="gbp" />,
46
- title: 'Wise GBP balance',
47
- content: (
48
- <>
49
- <span>300 GBP available</span>
50
- <span>0 GBP in fees, should arrive in seconds</span>
51
- </>
52
- ),
53
- disabled: true,
54
- value: { data: lorem10 },
55
- },
56
- cardPaymentMethod(1),
57
- {
58
- media: <Card />,
59
- title: 'Debit card',
60
- content: (
61
- <>
62
- <span>Send from your Visa or Mastercard.</span>
63
- <span>0.74 GBP in fees, should arrive in seconds</span>
64
- </>
65
- ),
66
- },
67
- {
68
- media: <Bank />,
69
- title: 'Swift Transfer',
70
- content: (
71
- <>
72
- <span>Send money internationally. Your bank will charge you extra fees.</span>
73
- <span>0.32 GBP in fees, should arrive by Thursday</span>
74
- </>
75
- ),
76
- },
77
- {
78
- media: <BankTransfer />,
79
- title: 'Bank Transfer',
80
- content: (
81
- <>
82
- <span>Transfer the money to Wise using your bank account.</span>
83
- <span>0.32 GBP in fees, should arrive in seconds</span>
84
- </>
85
- ),
86
- },
87
- {
88
- media: <BankTransfer />,
89
- title: 'Withdraw from your U.S. bank account (ACH)',
90
- content: (
91
- <>
92
- <span>1.63 USD in total fees.</span>
93
- <span>
94
- Pay with ACH using the bank account you’ve connected to Wise. Should arrive in seconds.
95
- </span>
96
- </>
97
- ),
98
- },
99
- cardPaymentMethod(1),
100
- cardPaymentMethod(2),
101
- cardPaymentMethod(3),
102
- cardPaymentMethod(4),
103
- cardPaymentMethod(5),
104
- cardPaymentMethod(6),
105
- ];
106
-
107
- const paymentMethods: SelectOptiopsSection<CustomData>[] = [
108
- {
109
- title: 'Recently used',
110
- options: recentPaymentMethods,
111
- },
112
- {
113
- title: 'Payment methods',
114
- options: allOtherPaymentMethods,
115
- },
116
- ];
117
-
118
- const balances: SelectOptiopsSection[] = [
119
- {
120
- title: 'Balances',
121
- options: [
122
- {
123
- media: <Flag code="gbp" />,
124
- title: 'Wise GBP balance',
125
- },
126
- {
127
- media: <Flag code="eur" />,
128
- title: 'Wise EUR balance',
129
- },
130
- ],
131
- },
132
- {
133
- title: 'Jars',
134
- options: [
135
- {
136
- media: (
137
- <Badge badge={<Flag code="usd" />} size="md">
138
- <Avatar type="icon" size="md" backgroundColor="var(--color-bright-pink)">
139
- <Beach size="24" />
140
- </Avatar>
141
- </Badge>
142
- ),
143
- title: 'Hawaii Holiday',
144
- content: 'Wise USD jar',
145
- },
146
- {
147
- media: (
148
- <Badge badge={<Flag code="aed" />} size="md">
149
- <Avatar type="icon" size="md" backgroundColor="var(--color-bright-yellow)">
150
- <Briefcase size="24" />
151
- </Avatar>
152
- </Badge>
153
- ),
154
- title: 'Emirates Business Trip',
155
- content: 'Wise AED jar',
156
- },
157
- {
158
- media: (
159
- <Badge badge={<Flag code="jpy" />} size="md">
160
- <Avatar type="icon" size="md" backgroundColor="var(--color-bright-blue)">
161
- <Plane size="24" />
162
- </Avatar>
163
- </Badge>
164
- ),
165
- title: 'Trip to Mars',
166
- content: 'Wise Jpy jar',
167
- },
168
- ],
169
- },
170
- ];
171
-
172
- export const Basic: Story = {
173
- args: {
174
- placeholder: { title: 'No balance selected' },
175
- options: balances,
176
- },
177
- render: (args: SelectOptionProps) => {
178
- const [selected, setSelected] = useState<SelectOptionValue | undefined>(undefined);
179
-
180
- function onChange(value: SelectOptionValue): void {
181
- setSelected(value);
182
- }
183
- return (
184
- <div className="row">
185
- <div className="col-md-8 col-md-offset-2">
186
- <Field label="Balances">
187
- <SelectOption {...args} {...{ selected, onChange }} />
188
- </Field>
189
- </div>
190
- </div>
191
- );
192
- },
193
- };
194
-
195
- export const Variants: Story = {
196
- render: () => {
197
- const [selected, setSelected] = useState<SelectOptionValue<CustomData>>({
198
- ...paymentMethods[1].options[1],
199
- content: null,
200
- });
201
- function onChange(value: SelectOptionValue<CustomData>): void {
202
- setSelected({ ...value, content: null });
203
- }
204
- return (
205
- <div className="row">
206
- <div className="col-md-8 col-md-offset-2">
207
- <SelectOption<CustomData>
208
- className="d-block"
209
- aria-label="Choose one of payment methods"
210
- placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
211
- selected={selected}
212
- options={paymentMethods}
213
- onChange={onChange}
214
- />
215
- </div>
216
-
217
- <div className="col-md-8 col-md-offset-2">
218
- <Field label={<>Payment method</>}>
219
- <SelectOption<CustomData>
220
- aria-label="Choose one of payment methods"
221
- placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
222
- selected={selected}
223
- options={paymentMethods}
224
- onChange={onChange}
225
- />
226
- </Field>
227
- </div>
228
-
229
- <div className="col-md-8 col-md-offset-2">
230
- <Field
231
- label={<>Payment method</>}
232
- sentiment={Sentiment.NEGATIVE}
233
- message="Just an example of validation message"
234
- >
235
- <SelectOption<CustomData>
236
- aria-label="Choose one of payment methods"
237
- placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
238
- selected={selected}
239
- options={paymentMethods}
240
- onChange={onChange}
241
- />
242
- </Field>
243
- </div>
244
-
245
- <div className="col-md-8 col-md-offset-2">
246
- <Field
247
- label={<>Payment method</>}
248
- sentiment={Sentiment.NEGATIVE}
249
- message="Just an example of validation message"
250
- >
251
- <SelectOption<CustomData>
252
- aria-label="Choose one of payment methods"
253
- placeholder={{ title: 'No method selected', actionLabel: 'Select' }}
254
- options={paymentMethods}
255
- onChange={onChange}
256
- />
257
- </Field>
258
- </div>
259
-
260
- <div className="col-md-8 col-md-offset-2">
261
- <Field
262
- label={<>Payment method</>}
263
- sentiment={Sentiment.NEGATIVE}
264
- message="Example of disabled select option"
265
- >
266
- <SelectOption<CustomData>
267
- disabled
268
- placeholder={{ title: 'No method selected' }}
269
- options={paymentMethods}
270
- onChange={onChange}
271
- />
272
- </Field>
273
- </div>
274
- </div>
275
- );
276
- },
277
- };
@@ -1,151 +0,0 @@
1
- import { useRef, useState } from 'react';
2
- import { ActionButtonProps } from '../actionButton';
3
- import { clsx } from 'clsx';
4
- import Option from '../common/Option';
5
- import type { OptionProps } from '../common/Option/Option';
6
- import { Breakpoint, Position } from '../common';
7
- import Section from '../section';
8
- import Header from '../header';
9
- import { HeaderProps } from '../header/Header';
10
- import NavigationOption from '../navigationOption';
11
- import NavigationOptionsList from '../navigationOptionsList';
12
- import { useInputAttributes } from '../inputs/contexts';
13
- import messages from './SelectOption.messages';
14
- import { useIntl } from 'react-intl';
15
- import ResponsivePanel from '../common/responsivePanel';
16
- import { useScreenSize } from '../common/hooks/useScreenSize';
17
- import { ChevronDown, Plus } from '@transferwise/icons';
18
-
19
- export type SelectOptiopsSection<T = unknown> = {
20
- title?: HeaderProps['title'];
21
- options: SelectOptionValue<T>[];
22
- };
23
-
24
- export type SelectOptionValue<T = unknown> = Pick<
25
- OptionProps,
26
- 'media' | 'title' | 'content' | 'disabled'
27
- > & {
28
- value?: T;
29
- };
30
-
31
- export type SelectOptionPlaceholder = Pick<OptionProps, 'media' | 'title' | 'content'> & {
32
- actionLabel?: ActionButtonProps['children'];
33
- };
34
-
35
- export type SelectOptionProps<T = unknown> = {
36
- onChange: (selected: SelectOptionValue<T>) => void;
37
- selected?: SelectOptionValue<T>;
38
- options: SelectOptiopsSection<T>[];
39
- placeholder: SelectOptionPlaceholder;
40
- } & Omit<
41
- OptionProps,
42
- 'as' | 'title' | 'media' | 'content' | 'onClick' | 'onChange' | 'showMediaAtAllSizes' | 'decision'
43
- >;
44
-
45
- export default function SelectOption<T>({
46
- selected = undefined,
47
- options,
48
- onChange,
49
- placeholder,
50
- disabled,
51
- ...props
52
- }: SelectOptionProps<T>) {
53
- const intl = useIntl();
54
- const rootRef = useRef(null);
55
- const [showOptions, setShowOptions] = useState(false);
56
-
57
- const hasSelected = selected !== undefined;
58
- const isLargeScreen = useScreenSize(Breakpoint.SMALL);
59
-
60
- const inputAttributes = useInputAttributes();
61
- const ariaLabelledBy = props['aria-labelledby'] ?? inputAttributes?.['aria-labelledby'];
62
-
63
- function handleOnClick(showOptionsStatus: boolean) {
64
- return () => {
65
- setShowOptions(showOptionsStatus);
66
- };
67
- }
68
-
69
- function handleOnChange(data: SelectOptionValue<T>) {
70
- return () => {
71
- setShowOptions(false);
72
- onChange(data);
73
- };
74
- }
75
-
76
- function getOptions(isLargeScreen = false) {
77
- return (
78
- <div className={clsx({ 'np-select-option-list': isLargeScreen })}>
79
- {options.map((optionsSection, index) => (
80
- <Section key={index} className={clsx({ 'p-x-2 p-y-1': isLargeScreen })}>
81
- {optionsSection.title && <Header title={optionsSection.title} />}
82
- <NavigationOptionsList>
83
- {optionsSection.options.map((option, index) => {
84
- return (
85
- <NavigationOption
86
- key={index}
87
- isContainerAligned={!isLargeScreen}
88
- showMediaCircle
89
- showMediaAtAllSizes
90
- onClick={handleOnChange(option)}
91
- {...option}
92
- />
93
- );
94
- })}
95
- </NavigationOptionsList>
96
- </Section>
97
- ))}
98
- </div>
99
- );
100
- }
101
-
102
- return (
103
- <>
104
- <Option
105
- ref={rootRef}
106
- as="div"
107
- showMediaAtAllSizes
108
- disabled={disabled}
109
- decision={false}
110
- media={hasSelected ? selected.media : (placeholder.media ?? <Plus size={24} />)}
111
- title={(hasSelected ? selected : placeholder).title}
112
- content={(hasSelected ? selected : placeholder).content}
113
- className={clsx(
114
- 'np-select-option',
115
- 'clickable',
116
- hasSelected ? 'np-select-option-selected' : 'np-select-option-placeholder',
117
- props.className,
118
- )}
119
- button={
120
- <button
121
- {...inputAttributes}
122
- type="button"
123
- disabled={disabled}
124
- aria-labelledby={ariaLabelledBy}
125
- aria-haspopup="dialog"
126
- aria-expanded={showOptions}
127
- className={hasSelected ? 'btn-unstyled' : 'np-action-btn'}
128
- aria-label={hasSelected ? undefined : props['aria-label']}
129
- onClick={handleOnClick(true)}
130
- >
131
- {hasSelected ? (
132
- <ChevronDown title={intl.formatMessage(messages.selectedActionLabel)} />
133
- ) : (
134
- placeholder.actionLabel || intl.formatMessage(messages.actionLabel)
135
- )}
136
- </button>
137
- }
138
- />
139
- <ResponsivePanel
140
- anchorWidth
141
- altAxis
142
- anchorRef={rootRef}
143
- open={showOptions}
144
- position={Position.BOTTOM}
145
- onClose={handleOnClick(false)}
146
- >
147
- {getOptions(isLargeScreen)}
148
- </ResponsivePanel>
149
- </>
150
- );
151
- }
@@ -1,2 +0,0 @@
1
- export { default } from './SelectOption';
2
- export type { SelectOptionProps, SelectOptionValue, SelectOptiopsSection } from './SelectOption';