@transferwise/components 45.19.6 → 45.21.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.
Files changed (135) hide show
  1. package/build/i18n/cs.json +11 -3
  2. package/build/i18n/de.json +11 -3
  3. package/build/i18n/en.json +1 -0
  4. package/build/i18n/es.json +11 -3
  5. package/build/i18n/fr.json +11 -3
  6. package/build/i18n/hu.json +11 -3
  7. package/build/i18n/id.json +11 -3
  8. package/build/i18n/it.json +11 -3
  9. package/build/i18n/ja.json +11 -3
  10. package/build/i18n/pl.json +11 -3
  11. package/build/i18n/pt.json +11 -3
  12. package/build/i18n/ro.json +11 -3
  13. package/build/i18n/ru.json +11 -3
  14. package/build/i18n/th.json +11 -3
  15. package/build/i18n/tr.json +11 -3
  16. package/build/i18n/uk.json +11 -3
  17. package/build/i18n/zh-CN.json +11 -3
  18. package/build/i18n/{zh.json → zh-HK.json} +11 -3
  19. package/build/index.esm.js +557 -248
  20. package/build/index.esm.js.map +1 -1
  21. package/build/index.js +557 -248
  22. package/build/index.js.map +1 -1
  23. package/build/main.css +1 -1
  24. package/build/styles/actionButton/ActionButton.css +1 -1
  25. package/build/styles/chips/Chip.css +1 -1
  26. package/build/styles/circularButton/CircularButton.css +1 -1
  27. package/build/styles/common/Option/Option.css +1 -1
  28. package/build/styles/common/bottomSheet/BottomSheet.css +1 -1
  29. package/build/styles/common/closeButton/CloseButton.css +1 -1
  30. package/build/styles/dateLookup/DateLookup.css +1 -1
  31. package/build/styles/drawer/Drawer.css +1 -1
  32. package/build/styles/flowNavigation/FlowNavigation.css +1 -1
  33. package/build/styles/inputs/SelectInput.css +1 -1
  34. package/build/styles/main.css +1 -1
  35. package/build/styles/overlayHeader/OverlayHeader.css +1 -1
  36. package/build/styles/statusIcon/StatusIcon.css +1 -1
  37. package/build/styles/summary/Summary.css +1 -1
  38. package/build/styles/typeahead/Typeahead.css +1 -1
  39. package/build/styles/uploadInput/UploadInput.css +1 -1
  40. package/build/types/common/bottomSheet/BottomSheet.d.ts.map +1 -1
  41. package/build/types/common/locale/index.d.ts +10 -1
  42. package/build/types/common/locale/index.d.ts.map +1 -1
  43. package/build/types/common/propsValues/breakpoint.d.ts +1 -0
  44. package/build/types/common/propsValues/breakpoint.d.ts.map +1 -1
  45. package/build/types/dateLookup/DateLookup.d.ts.map +1 -1
  46. package/build/types/dateLookup/dateHeader/DateHeader.d.ts.map +1 -1
  47. package/build/types/i18n/index.d.ts.map +1 -1
  48. package/build/types/inputs/SelectInput.d.ts +6 -3
  49. package/build/types/inputs/SelectInput.d.ts.map +1 -1
  50. package/build/types/inputs/SelectInput.messages.d.ts +9 -0
  51. package/build/types/inputs/SelectInput.messages.d.ts.map +1 -0
  52. package/build/types/inputs/_Popover.d.ts +2 -2
  53. package/build/types/inputs/_Popover.d.ts.map +1 -1
  54. package/build/types/test-utils/story-config.d.ts +11 -1
  55. package/build/types/test-utils/story-config.d.ts.map +1 -1
  56. package/build/types/test-utils/window-mock.d.ts +2 -0
  57. package/build/types/test-utils/window-mock.d.ts.map +1 -0
  58. package/package.json +4 -4
  59. package/src/actionButton/ActionButton.css +1 -1
  60. package/src/actionButton/ActionButton.less +5 -1
  61. package/src/chips/Chip.css +1 -1
  62. package/src/chips/Chip.less +8 -0
  63. package/src/circularButton/CircularButton.css +1 -1
  64. package/src/circularButton/CircularButton.less +9 -3
  65. package/src/common/Option/Option.css +1 -1
  66. package/src/common/Option/Option.less +6 -0
  67. package/src/common/bottomSheet/BottomSheet.css +1 -1
  68. package/src/common/bottomSheet/BottomSheet.less +1 -1
  69. package/src/common/bottomSheet/BottomSheet.spec.tsx +4 -1
  70. package/src/common/bottomSheet/BottomSheet.story.tsx +4 -0
  71. package/src/common/bottomSheet/BottomSheet.tsx +10 -1
  72. package/src/common/closeButton/CloseButton.css +1 -1
  73. package/src/common/closeButton/CloseButton.less +12 -0
  74. package/src/common/hooks/useMedia.spec.ts +3 -17
  75. package/src/common/locale/index.js +10 -1
  76. package/src/common/locale/index.spec.js +1 -34
  77. package/src/common/propsValues/breakpoint.ts +1 -0
  78. package/src/dateLookup/DateLookup.css +1 -1
  79. package/src/dateLookup/DateLookup.js +7 -3
  80. package/src/dateLookup/DateLookup.keyboardEvents.spec.js +3 -0
  81. package/src/dateLookup/DateLookup.less +6 -0
  82. package/src/dateLookup/DateLookup.story.js +6 -1
  83. package/src/dateLookup/DateLookup.testingLibrary.spec.js +3 -1
  84. package/src/dateLookup/DateLookup.view.spec.js +4 -0
  85. package/src/dateLookup/dateHeader/DateHeader.js +4 -2
  86. package/src/drawer/Drawer.css +1 -1
  87. package/src/drawer/Drawer.less +6 -8
  88. package/src/drawer/Drawer.story.js +42 -2
  89. package/src/flowNavigation/FlowNavigation.css +1 -1
  90. package/src/i18n/cs.json +11 -3
  91. package/src/i18n/de.json +11 -3
  92. package/src/i18n/en.json +1 -0
  93. package/src/i18n/es.json +11 -3
  94. package/src/i18n/fr.json +11 -3
  95. package/src/i18n/hu.json +11 -3
  96. package/src/i18n/id.json +11 -3
  97. package/src/i18n/index.ts +6 -2
  98. package/src/i18n/it.json +11 -3
  99. package/src/i18n/ja.json +11 -3
  100. package/src/i18n/pl.json +11 -3
  101. package/src/i18n/pt.json +11 -3
  102. package/src/i18n/ro.json +11 -3
  103. package/src/i18n/ru.json +11 -3
  104. package/src/i18n/th.json +11 -3
  105. package/src/i18n/tr.json +11 -3
  106. package/src/i18n/uk.json +11 -3
  107. package/src/i18n/zh-CN.json +11 -3
  108. package/src/i18n/{zh.json → zh-HK.json} +11 -3
  109. package/src/inputs/SelectInput.css +1 -1
  110. package/src/inputs/SelectInput.less +29 -7
  111. package/src/inputs/SelectInput.messages.ts +9 -0
  112. package/src/inputs/SelectInput.story.tsx +8 -5
  113. package/src/inputs/SelectInput.tsx +91 -33
  114. package/src/inputs/_BottomSheet.tsx +19 -19
  115. package/src/inputs/_Popover.tsx +2 -2
  116. package/src/main.css +1 -1
  117. package/src/modal/Modal.tsx +2 -2
  118. package/src/overlayHeader/OverlayHeader.css +1 -1
  119. package/src/popover/Popover.spec.js +3 -1
  120. package/src/radioGroup/RadioGroup.js +1 -1
  121. package/src/radioGroup/RadioGroup.spec.js +18 -0
  122. package/src/select/Select.spec.js +6 -9
  123. package/src/statusIcon/StatusIcon.css +1 -1
  124. package/src/statusIcon/StatusIcon.less +10 -0
  125. package/src/summary/Summary.css +1 -1
  126. package/src/summary/Summary.less +1 -1
  127. package/src/test-utils/index.js +1 -0
  128. package/src/test-utils/story-config.ts +21 -7
  129. package/src/test-utils/window-mock.ts +19 -0
  130. package/src/typeahead/Typeahead.css +1 -1
  131. package/src/typeahead/Typeahead.less +5 -6
  132. package/src/uploadInput/UploadInput.css +1 -1
  133. package/src/uploadInput/UploadInput.less +5 -1
  134. package/build/i18n/zh_CN.json +0 -44
  135. package/src/i18n/zh_CN.json +0 -44
package/src/i18n/pl.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "ładowanie",
2
3
  "neptune.Chips.ariaLabel": "Wyczyść {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "Wyczyść",
4
5
  "neptune.CloseButton.ariaLabel": "Zamknij",
5
6
  "neptune.DateInput.day.label": "Dzień",
6
7
  "neptune.DateInput.month.label": "Miesiąc",
7
8
  "neptune.DateInput.year.label": "Rok",
9
+ "neptune.DateLookup.day": "dzień",
10
+ "neptune.DateLookup.goTo20YearView": "Przejdź do widoku 20-letniego",
11
+ "neptune.DateLookup.month": "miesiąc",
12
+ "neptune.DateLookup.next": "następny",
13
+ "neptune.DateLookup.previous": "poprzedni",
14
+ "neptune.DateLookup.selected": "wybrano",
15
+ "neptune.DateLookup.twentyYears": "20 lat",
16
+ "neptune.DateLookup.year": "rok",
17
+ "neptune.FlowNavigation.back": "wróć do poprzedniego kroku",
18
+ "neptune.Link.opensInNewTab": "(otworzy się w nowej zakładce)",
8
19
  "neptune.MoneyInput.Select.placeholder": "Wybierz opcję...",
9
- "neptune.Pagination.ariaLabel": "Nawigacja w paginacji",
10
- "neptune.PaginationLink.ariaLabel.active": "Przejdź do strony {pageNumber}",
11
- "neptune.PaginationLink.ariaLabel.inactive": "Obecna strona, strona {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "Wyszukaj...",
13
21
  "neptune.Summary.statusDone": "Czynność wykonana",
14
22
  "neptune.Summary.statusNotDone": "Czynność do wykonania",
package/src/i18n/pt.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "carregando",
2
3
  "neptune.Chips.ariaLabel": "Remover {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "Remover",
4
5
  "neptune.CloseButton.ariaLabel": "Fechar",
5
6
  "neptune.DateInput.day.label": "Dia",
6
7
  "neptune.DateInput.month.label": "Mês",
7
8
  "neptune.DateInput.year.label": "Ano",
9
+ "neptune.DateLookup.day": "dia",
10
+ "neptune.DateLookup.goTo20YearView": "Go to 20 year view",
11
+ "neptune.DateLookup.month": "mês",
12
+ "neptune.DateLookup.next": "próximo",
13
+ "neptune.DateLookup.previous": "anterior",
14
+ "neptune.DateLookup.selected": "selecionada",
15
+ "neptune.DateLookup.twentyYears": "20 anos",
16
+ "neptune.DateLookup.year": "ano",
17
+ "neptune.FlowNavigation.back": "back to previous step",
18
+ "neptune.Link.opensInNewTab": "(abrir a página em uma nova aba)",
8
19
  "neptune.MoneyInput.Select.placeholder": "Escolha uma opção...",
9
- "neptune.Pagination.ariaLabel": "Navegação pelas páginas",
10
- "neptune.PaginationLink.ariaLabel.active": "Ir para a página {pageNumber}",
11
- "neptune.PaginationLink.ariaLabel.inactive": "Página atual, página {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "Buscar...",
13
21
  "neptune.Summary.statusDone": "Pronto",
14
22
  "neptune.Summary.statusNotDone": "Não iniciado",
package/src/i18n/ro.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "se încarcă",
2
3
  "neptune.Chips.ariaLabel": "Șterge {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "Elimină",
4
5
  "neptune.CloseButton.ariaLabel": "Închide",
5
6
  "neptune.DateInput.day.label": "Zi",
6
7
  "neptune.DateInput.month.label": "Lună",
7
8
  "neptune.DateInput.year.label": "An",
9
+ "neptune.DateLookup.day": "zi",
10
+ "neptune.DateLookup.goTo20YearView": "Accesează vizualizarea pe 20 de ani",
11
+ "neptune.DateLookup.month": "luna",
12
+ "neptune.DateLookup.next": "înainte",
13
+ "neptune.DateLookup.previous": "precedenta",
14
+ "neptune.DateLookup.selected": "selectată",
15
+ "neptune.DateLookup.twentyYears": "20 de ani",
16
+ "neptune.DateLookup.year": "anul",
17
+ "neptune.FlowNavigation.back": "înapoi la pasul anterior",
18
+ "neptune.Link.opensInNewTab": "(se deschide într-o filă nouă)",
8
19
  "neptune.MoneyInput.Select.placeholder": "Selectează o opţiune...",
9
- "neptune.Pagination.ariaLabel": "Navigare prin pagină",
10
- "neptune.PaginationLink.ariaLabel.active": "Du-te la pagina {pageNumber}",
11
- "neptune.PaginationLink.ariaLabel.inactive": "Pagina curentă, pagina {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "Caută...",
13
21
  "neptune.Summary.statusDone": "Finalizat",
14
22
  "neptune.Summary.statusNotDone": "De făcut",
package/src/i18n/ru.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "загрузка",
2
3
  "neptune.Chips.ariaLabel": "Очистить {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "Очистить",
4
5
  "neptune.CloseButton.ariaLabel": "Закрыть",
5
6
  "neptune.DateInput.day.label": "День",
6
7
  "neptune.DateInput.month.label": "Месяц",
7
8
  "neptune.DateInput.year.label": "Год",
9
+ "neptune.DateLookup.day": "день",
10
+ "neptune.DateLookup.goTo20YearView": "Перейти к обзору 20 лет",
11
+ "neptune.DateLookup.month": "месяц",
12
+ "neptune.DateLookup.next": "далее",
13
+ "neptune.DateLookup.previous": "предыдущий",
14
+ "neptune.DateLookup.selected": "выбрано",
15
+ "neptune.DateLookup.twentyYears": "20 лет",
16
+ "neptune.DateLookup.year": "год",
17
+ "neptune.FlowNavigation.back": "вернуться к предыдущему шагу",
18
+ "neptune.Link.opensInNewTab": "(откроется в новой вкладке)",
8
19
  "neptune.MoneyInput.Select.placeholder": "Выберите вариант...",
9
- "neptune.Pagination.ariaLabel": "Постраничная навигация",
10
- "neptune.PaginationLink.ariaLabel.active": "Перейти на страницу {pageNumber}",
11
- "neptune.PaginationLink.ariaLabel.inactive": "Текущая страница, страница {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "Поиск...",
13
21
  "neptune.Summary.statusDone": "Этап завершен",
14
22
  "neptune.Summary.statusNotDone": "Этап к выполнению",
package/src/i18n/th.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "กำลังโหลด",
2
3
  "neptune.Chips.ariaLabel": "เคลียร์ {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "ชัดเจน",
4
5
  "neptune.CloseButton.ariaLabel": "ปิด",
5
6
  "neptune.DateInput.day.label": "วัน",
6
7
  "neptune.DateInput.month.label": "เดือน",
7
8
  "neptune.DateInput.year.label": "ปี",
9
+ "neptune.DateLookup.day": "วัน",
10
+ "neptune.DateLookup.goTo20YearView": "Go to 20 year view",
11
+ "neptune.DateLookup.month": "เดือน",
12
+ "neptune.DateLookup.next": "ถัดไป",
13
+ "neptune.DateLookup.previous": "ก่อนหน้า",
14
+ "neptune.DateLookup.selected": "เลือกแล้ว",
15
+ "neptune.DateLookup.twentyYears": "20 ปี",
16
+ "neptune.DateLookup.year": "ปี",
17
+ "neptune.FlowNavigation.back": "back to previous step",
18
+ "neptune.Link.opensInNewTab": "(opens in new tab)",
8
19
  "neptune.MoneyInput.Select.placeholder": "เลือกตัวเลือก...",
9
- "neptune.Pagination.ariaLabel": "การนำทางเลขหน้า",
10
- "neptune.PaginationLink.ariaLabel.active": "ไปที่หน้า {pageNumber}",
11
- "neptune.PaginationLink.ariaLabel.inactive": "หน้าปัจจุบัน หน้า {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "ค้นหา...",
13
21
  "neptune.Summary.statusDone": "รายการที่ทำแล้ว",
14
22
  "neptune.Summary.statusNotDone": "รายการที่ต้องทำ",
package/src/i18n/tr.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "yükleniyor",
2
3
  "neptune.Chips.ariaLabel": "{choice} temizle",
3
4
  "neptune.ClearButton.ariaLabel": "Sil",
4
5
  "neptune.CloseButton.ariaLabel": "Kapat",
5
6
  "neptune.DateInput.day.label": "Gün",
6
7
  "neptune.DateInput.month.label": "Ay",
7
8
  "neptune.DateInput.year.label": "Yıl",
9
+ "neptune.DateLookup.day": "gün",
10
+ "neptune.DateLookup.goTo20YearView": "20 yıl görünümüne git",
11
+ "neptune.DateLookup.month": "ay",
12
+ "neptune.DateLookup.next": "devam et",
13
+ "neptune.DateLookup.previous": "önceki",
14
+ "neptune.DateLookup.selected": "seçili",
15
+ "neptune.DateLookup.twentyYears": "20 yıl",
16
+ "neptune.DateLookup.year": "yıl",
17
+ "neptune.FlowNavigation.back": "önceki adıma dön",
18
+ "neptune.Link.opensInNewTab": "(yeni sekmede açılır)",
8
19
  "neptune.MoneyInput.Select.placeholder": "Bir seçenek seçin...",
9
- "neptune.Pagination.ariaLabel": "Sayfalandırma gezintisi",
10
- "neptune.PaginationLink.ariaLabel.active": "{pageNumber} numaralı sayfaya git",
11
- "neptune.PaginationLink.ariaLabel.inactive": "Mevcut sayfa, sayfa {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "Ara...",
13
21
  "neptune.Summary.statusDone": "Tamamlanan aşama",
14
22
  "neptune.Summary.statusNotDone": "Yapılacak",
package/src/i18n/uk.json CHANGED
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "завантаження",
2
3
  "neptune.Chips.ariaLabel": "Очистити {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "Очистити",
4
5
  "neptune.CloseButton.ariaLabel": "Закрити",
5
6
  "neptune.DateInput.day.label": "День",
6
7
  "neptune.DateInput.month.label": "Місяць",
7
8
  "neptune.DateInput.year.label": "Рік",
9
+ "neptune.DateLookup.day": "дня",
10
+ "neptune.DateLookup.goTo20YearView": "Go to 20 year view",
11
+ "neptune.DateLookup.month": "місяць",
12
+ "neptune.DateLookup.next": "уперед",
13
+ "neptune.DateLookup.previous": "назад",
14
+ "neptune.DateLookup.selected": "вибрано",
15
+ "neptune.DateLookup.twentyYears": "20 років",
16
+ "neptune.DateLookup.year": "рік",
17
+ "neptune.FlowNavigation.back": "back to previous step",
18
+ "neptune.Link.opensInNewTab": "(opens in new tab)",
8
19
  "neptune.MoneyInput.Select.placeholder": "Виберіть варіант…",
9
- "neptune.Pagination.ariaLabel": "Перехід за сторінками",
10
- "neptune.PaginationLink.ariaLabel.active": "Перейти на сторінку {pageNumber}",
11
- "neptune.PaginationLink.ariaLabel.inactive": "Ця сторінка, сторінка {pageNumber}",
12
20
  "neptune.Select.searchPlaceholder": "Пошук…",
13
21
  "neptune.Summary.statusDone": "Виконано",
14
22
  "neptune.Summary.statusNotDone": "Не виконано",
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "正在加载",
2
3
  "neptune.Chips.ariaLabel": "清除 {choice}",
3
4
  "neptune.ClearButton.ariaLabel": "清晰",
4
5
  "neptune.CloseButton.ariaLabel": "关闭",
5
6
  "neptune.DateInput.day.label": "日",
6
7
  "neptune.DateInput.month.label": "月",
7
8
  "neptune.DateInput.year.label": "年",
9
+ "neptune.DateLookup.day": "日",
10
+ "neptune.DateLookup.goTo20YearView": "Go to 20 year view",
11
+ "neptune.DateLookup.month": "月",
12
+ "neptune.DateLookup.next": "下一页",
13
+ "neptune.DateLookup.previous": "上一页",
14
+ "neptune.DateLookup.selected": "已选",
15
+ "neptune.DateLookup.twentyYears": "20年",
16
+ "neptune.DateLookup.year": "年",
17
+ "neptune.FlowNavigation.back": "back to previous step",
18
+ "neptune.Link.opensInNewTab": "(opens in new tab)",
8
19
  "neptune.MoneyInput.Select.placeholder": "请选择...",
9
- "neptune.Pagination.ariaLabel": "分页导航",
10
- "neptune.PaginationLink.ariaLabel.active": "转到第 {pageNumber} 页",
11
- "neptune.PaginationLink.ariaLabel.inactive": "当前页面,第 {pageNumber} 页",
12
20
  "neptune.Select.searchPlaceholder": "搜索",
13
21
  "neptune.Summary.statusDone": "已完成",
14
22
  "neptune.Summary.statusNotDone": "未完成",
@@ -1,14 +1,22 @@
1
1
  {
2
+ "neptune.Button.loadingAriaLabel": "載入中",
2
3
  "neptune.Chips.ariaLabel": "清除{choice}",
3
4
  "neptune.ClearButton.ariaLabel": "清除",
4
5
  "neptune.CloseButton.ariaLabel": "關閉",
5
6
  "neptune.DateInput.day.label": "日",
6
7
  "neptune.DateInput.month.label": "月",
7
8
  "neptune.DateInput.year.label": "年",
9
+ "neptune.DateLookup.day": "日",
10
+ "neptune.DateLookup.goTo20YearView": "切換至20年視圖",
11
+ "neptune.DateLookup.month": "月",
12
+ "neptune.DateLookup.next": "下一個",
13
+ "neptune.DateLookup.previous": "上一個",
14
+ "neptune.DateLookup.selected": "已選",
15
+ "neptune.DateLookup.twentyYears": "20年",
16
+ "neptune.DateLookup.year": "年",
17
+ "neptune.FlowNavigation.back": "返回上一個步驟",
18
+ "neptune.Link.opensInNewTab": "(在新分頁中開啟)",
8
19
  "neptune.MoneyInput.Select.placeholder": "選擇一個選項…",
9
- "neptune.Pagination.ariaLabel": "分頁導航",
10
- "neptune.PaginationLink.ariaLabel.active": "前往第{pageNumber}頁",
11
- "neptune.PaginationLink.ariaLabel.inactive": "目前在第{pageNumber}頁",
12
20
  "neptune.Select.searchPlaceholder": "搜尋…",
13
21
  "neptune.Summary.statusDone": "已完成事項",
14
22
  "neptune.Summary.statusNotDone": "未完成事項",
@@ -1 +1 @@
1
- .np-bottom-sheet-v2-container{position:relative;z-index:1060}.np-bottom-sheet-v2-backdrop-container--enter,.np-bottom-sheet-v2-backdrop-container--leave{transition-duration:.15s;transition-property:opacity;transition-timing-function:ease-out}.np-bottom-sheet-v2-backdrop-container--enter-from,.np-bottom-sheet-v2-backdrop-container--leave-to{opacity:0}.np-bottom-sheet-v2-backdrop{background-color:#37517e;background-color:var(--color-content-primary);inset:0;opacity:.4;position:fixed}.np-bottom-sheet-v2{display:flex;flex-direction:column;inset:0;justify-content:flex-end;padding-left:8px;padding-left:var(--size-8);padding-right:8px;padding-right:var(--size-8);padding-top:64px;padding-top:var(--size-64);position:fixed}.np-bottom-sheet-v2-content{max-height:100%}.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-duration:.3s;transition-property:transform;transition-timing-function:ease-out}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-property:opacity}}@media (prefers-reduced-motion:no-preference){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{transform:translateY(100%)}}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{opacity:0}}.np-bottom-sheet-v2-content-inner-container{background-color:#fff;background-color:var(--color-background-elevated);border-top-left-radius:32px;border-top-right-radius:32px;box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;height:100%}.np-bottom-sheet-v2-content-inner-container:focus{outline:none}.np-bottom-sheet-v2-header{align-self:flex-end;padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-content-inner{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;padding-top:0;row-gap:8px;row-gap:var(--size-8)}.np-bottom-sheet-v2-content-inner--has-title{grid-template-rows:auto 1fr}.np-bottom-sheet-v2-content-inner--padding-md{padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-title{color:#37517e;color:var(--color-content-primary)}.np-bottom-sheet-v2-body{color:#5d7079;color:var(--color-content-secondary)}.np-button-input{align-content:center;border-radius:10px;border-radius:var(--size-10);display:inline-grid;grid-auto-columns:minmax(0,1fr);text-align:start}.np-popover-v2-container{background-color:#fff;background-color:var(--color-background-elevated);border-radius:10px;border-radius:var(--radius-small);box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;max-height:var(--max-height);min-width:20rem;width:var(--width);z-index:1060}.np-popover-v2-container:focus{outline:none}.np-popover-v2{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;row-gap:8px;row-gap:var(--size-8)}.np-popover-v2--has-title{grid-template-rows:auto 1fr}.np-popover-v2--padding-md{padding:16px;padding:var(--size-16)}.np-popover-v2-title{color:#37517e;color:var(--color-content-primary)}.np-popover-v2-content{color:#5d7079;color:var(--color-content-secondary)}.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);cursor:default;display:flex;padding:12px 16px;padding:var(--size-12) var(--size-16);-webkit-user-select:none;-moz-user-select:none;user-select:none}.np-select-input-option-container--selected{box-shadow:inset 0 0 0 1px #c9cbce;box-shadow:inset 0 0 0 1px var(--color-interactive-secondary)}.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{color:var(--color-interactive-primary)}.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-within-trigger{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-primary{font:inherit}.np-select-input-option-content-text-secondary{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-option-content-text-within-trigger{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-container,.np-select-input-addon-container>:not([hidden])~:not([hidden]){margin-inline-start:4px;margin-inline-start:var(--size-4)}.np-select-input-addon{align-items:center;background:none;border-radius:.125rem;border-width:0;display:inline-flex;height:24px;height:var(--size-24);justify-content:center;width:24px;width:var(--size-24)}.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:1px solid #0000001a;border-inline-start:1px solid var(--color-border-neutral);height:24px;height:var(--size-24)}
1
+ .np-bottom-sheet-v2-container{position:relative;z-index:1060}.np-bottom-sheet-v2-backdrop-container--enter,.np-bottom-sheet-v2-backdrop-container--leave{transition-duration:.15s;transition-property:opacity;transition-timing-function:ease-out}.np-bottom-sheet-v2-backdrop-container--enter-from,.np-bottom-sheet-v2-backdrop-container--leave-to{opacity:0}.np-bottom-sheet-v2-backdrop{background-color:#37517e;background-color:var(--color-content-primary);inset:0;opacity:.4;position:fixed}.np-bottom-sheet-v2{display:flex;flex-direction:column;inset:0;justify-content:flex-end;padding-left:8px;padding-left:var(--size-8);padding-right:8px;padding-right:var(--size-8);padding-top:64px;padding-top:var(--size-64);position:fixed}.np-bottom-sheet-v2-content{max-height:100%}.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-duration:.3s;transition-property:transform;transition-timing-function:ease-out}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter,.np-bottom-sheet-v2-content--leave{transition-property:opacity}}@media (prefers-reduced-motion:no-preference){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{transform:translateY(100%)}}@media (prefers-reduced-motion:reduce){.np-bottom-sheet-v2-content--enter-from,.np-bottom-sheet-v2-content--leave-to{opacity:0}}.np-bottom-sheet-v2-content-inner-container{background-color:#fff;background-color:var(--color-background-elevated);border-top-left-radius:32px;border-top-right-radius:32px;box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;height:100%}.np-bottom-sheet-v2-content-inner-container:focus{outline:none}.np-bottom-sheet-v2-header{align-self:flex-end;padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-content-inner{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;padding-top:0;row-gap:8px;row-gap:var(--size-8)}.np-bottom-sheet-v2-content-inner--has-title{grid-template-rows:auto 1fr}.np-bottom-sheet-v2-content-inner--padding-md{padding:16px;padding:var(--size-16)}.np-bottom-sheet-v2-title{color:#37517e;color:var(--color-content-primary)}.np-bottom-sheet-v2-body{color:#5d7079;color:var(--color-content-secondary)}.np-button-input{align-content:center;border-radius:10px;border-radius:var(--size-10);display:inline-grid;grid-auto-columns:minmax(0,1fr);text-align:start}.np-popover-v2-container{background-color:#fff;background-color:var(--color-background-elevated);border-radius:10px;border-radius:var(--radius-small);box-shadow:0 0 40px rgba(69,71,69,.2);display:flex;flex-direction:column;max-height:var(--max-height);min-width:20rem;width:var(--width);z-index:1060}.np-popover-v2-container:focus{outline:none}.np-popover-v2{display:grid;grid-template-rows:repeat(1,minmax(0,1fr));overflow-y:auto;row-gap:8px;row-gap:var(--size-8)}.np-popover-v2--has-title{grid-template-rows:auto 1fr}.np-popover-v2--padding-md{padding:16px;padding:var(--size-16)}.np-popover-v2-title{color:#37517e;color:var(--color-content-primary)}.np-popover-v2-content{color:#5d7079;color:var(--color-content-secondary)}.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-options-status{align-items:center;-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);display:flex;padding:8px 24px 0;padding:var(--size-8) var(--size-24) 0}.np-select-input-options-status-icon{color:#768e9c;color:var(--color-content-tertiary);padding:0 4px;padding:0 var(--size-4)}.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:var(--color-interactive-primary);-moz-column-gap:8px;column-gap:8px;-moz-column-gap:var(--size-8);column-gap:var(--size-8);cursor:default;display:flex;padding:12px 16px;padding:var(--size-12) var(--size-16);-webkit-user-select:none;-moz-user-select:none;user-select:none}.np-select-input-option-container--active{background-color:var(--color-interactive-primary)}.np-select-input-option-container--active.np-select-input-option-container--active *{color:var(--color-interactive-contrast)}.np-select-input-option-container--disabled{opacity:.45}.np-select-input-option-check{padding:0 4px;padding:0 var(--size-4)}.np-select-input-option-check--not-selected{visibility:hidden}.np-select-input-option-check-placeholder{display:inline-block;margin-inline-start:16px;margin-inline-start:var(--size-16);width:16px;width:var(--size-16)}.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-within-trigger{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-primary{font:inherit}.np-select-input-option-content-text-secondary{color:#5d7079;color:var(--color-content-secondary)}.np-select-input-option-content-text-within-trigger{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-container,.np-select-input-addon-container>:not([hidden])~:not([hidden]){margin-inline-start:4px;margin-inline-start:var(--size-4)}.np-select-input-addon{align-items:center;background:none;border-radius:.125rem;border-width:0;display:inline-flex;height:24px;height:var(--size-24);justify-content:center;width:24px;width:var(--size-24)}.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:1px solid #0000001a;border-inline-start:1px solid var(--color-border-neutral);height:24px;height:var(--size-24)}
@@ -26,6 +26,18 @@
26
26
  }
27
27
  }
28
28
 
29
+ .np-select-input-options-status {
30
+ display: flex;
31
+ align-items: center;
32
+ column-gap: var(--size-8);
33
+ padding: var(--size-8) var(--size-24) 0px;
34
+ }
35
+
36
+ .np-select-input-options-status-icon {
37
+ padding: 0 var(--size-4);
38
+ color: var(--color-content-tertiary);
39
+ }
40
+
29
41
  .np-select-input-query-container {
30
42
  display: flex;
31
43
  flex-direction: column;
@@ -93,14 +105,14 @@
93
105
  column-gap: var(--size-8);
94
106
  border-radius: var(--radius-small);
95
107
  padding: var(--size-12) var(--size-16);
96
- color: var(--color-content-primary);
97
-
98
- &--selected {
99
- box-shadow: inset 0 0 0 1px var(--color-interactive-secondary);
100
- }
108
+ color: var(--color-interactive-primary);
101
109
 
102
110
  &--active {
103
- background-color: var(--color-background-screen-hover);
111
+ background-color: var(--color-interactive-primary);
112
+
113
+ && * {
114
+ color: var(--color-interactive-contrast);
115
+ }
104
116
  }
105
117
 
106
118
  &--disabled {
@@ -109,7 +121,17 @@
109
121
  }
110
122
 
111
123
  .np-select-input-option-check {
112
- color: var(--color-interactive-primary);
124
+ padding: 0 var(--size-4);
125
+
126
+ &--not-selected {
127
+ visibility: hidden;
128
+ }
129
+ }
130
+
131
+ .np-select-input-option-check-placeholder {
132
+ margin-inline-start: var(--size-16);
133
+ display: inline-block;
134
+ width: var(--size-16);
113
135
  }
114
136
 
115
137
  .np-select-input-option {
@@ -0,0 +1,9 @@
1
+ import { defineMessages } from 'react-intl';
2
+
3
+ export default defineMessages({
4
+ noResultsFound: {
5
+ id: 'neptune.SelectInput.noResultsFound',
6
+ defaultMessage: 'No results found',
7
+ description: 'When a user-initiated search produces no results.',
8
+ },
9
+ });
@@ -131,6 +131,10 @@ export const Basic: StoryObj<{
131
131
  action: 'cleared',
132
132
  },
133
133
  },
134
+ play: ({ canvasElement }) => {
135
+ const triggerButton = within(canvasElement).getByRole('button');
136
+ userEvent.click(triggerButton);
137
+ },
134
138
  };
135
139
 
136
140
  interface Month {
@@ -180,11 +184,10 @@ export const Months: StoryObj<{
180
184
  action: 'cleared',
181
185
  },
182
186
  },
183
- };
184
-
185
- Months.play = ({ canvasElement }) => {
186
- const canvas = within(canvasElement);
187
- userEvent.click(canvas.getByText('January'));
187
+ play: ({ canvasElement }) => {
188
+ const triggerButton = within(canvasElement).getByText('January');
189
+ userEvent.click(triggerButton);
190
+ },
188
191
  };
189
192
 
190
193
  interface Currency {
@@ -1,6 +1,6 @@
1
1
  import { Listbox as ListboxBase } from '@headlessui/react';
2
2
  import { useId } from '@radix-ui/react-id';
3
- import { Check, ChevronDown, Cross } from '@transferwise/icons';
3
+ import { Check, ChevronDown, Cross, CrossCircle } from '@transferwise/icons';
4
4
  import classNames from 'classnames';
5
5
  import mergeProps from 'merge-props';
6
6
  import { createContext, forwardRef, useContext, useEffect, useMemo, useRef, useState } from 'react';
@@ -11,11 +11,13 @@ import { useEffectEvent } from '../common/hooks/useEffectEvent';
11
11
  import { useScreenSize } from '../common/hooks/useScreenSize';
12
12
  import { PolymorphicWithOverrides } from '../common/polymorphicWithOverrides/PolymorphicWithOverrides';
13
13
  import { Breakpoint } from '../common/propsValues/breakpoint';
14
- import messages from '../dateLookup/dateTrigger/DateTrigger.messages';
14
+ import dateTriggerMessages from '../dateLookup/dateTrigger/DateTrigger.messages';
15
15
  import { wrapInFragment } from '../utilities/wrapInFragment';
16
+ import { Merge } from '../utils';
16
17
 
17
18
  import { InputGroup } from './InputGroup';
18
19
  import { SearchInput } from './SearchInput';
20
+ import messages from './SelectInput.messages';
19
21
  import { BottomSheet } from './_BottomSheet';
20
22
  import { ButtonInput } from './_ButtonInput';
21
23
  import { Popover } from './_Popover';
@@ -38,7 +40,17 @@ function inferSearchableStrings(value: unknown) {
38
40
  return [];
39
41
  }
40
42
 
41
- const SelectInputHasValueContext = createContext(false);
43
+ const SelectInputItemCheckPaddingContext = createContext(false);
44
+
45
+ function useSelectInputItemCheckPadding() {
46
+ const checkPadding = useContext(SelectInputItemCheckPaddingContext);
47
+
48
+ // Avoid layout shifts during transitions via caching
49
+ const [initialCheckPadding] = useState(checkPadding);
50
+
51
+ return initialCheckPadding;
52
+ }
53
+
42
54
  const SelectInputTriggerButtonPropsContext = createContext<{
43
55
  ref?: React.ForwardedRef<HTMLButtonElement>;
44
56
  onClick?: () => void;
@@ -72,14 +84,11 @@ function dedupeSelectInputOptionItem<T>(
72
84
  item: SelectInputOptionItem<T>,
73
85
  existingValues: Set<T>,
74
86
  ): SelectInputOptionItem<T | undefined> {
75
- if (existingValues.has(item.value)) {
76
- return {
77
- ...item,
78
- value: undefined,
79
- };
87
+ if (!existingValues.has(item.value)) {
88
+ existingValues.add(item.value);
89
+ return item;
80
90
  }
81
- existingValues.add(item.value);
82
- return item;
91
+ return { ...item, value: undefined };
83
92
  }
84
93
 
85
94
  function dedupeSelectInputItems<T>(
@@ -105,6 +114,27 @@ function dedupeSelectInputItems<T>(
105
114
  });
106
115
  }
107
116
 
117
+ function filterSelectInputOptionItem<T>(item: SelectInputOptionItem<T>, needle: string) {
118
+ return inferSearchableStrings(item.filterMatchers ?? item.value).some((haystack) =>
119
+ haystack.includes(needle),
120
+ );
121
+ }
122
+
123
+ function filterSelectInputItems<T>(items: readonly SelectInputItem<T>[], needle: string) {
124
+ return items.filter((item) => {
125
+ switch (item.type) {
126
+ case 'option': {
127
+ return filterSelectInputOptionItem(item, needle);
128
+ }
129
+ case 'group': {
130
+ return item.options.some((option) => filterSelectInputOptionItem(option, needle));
131
+ }
132
+ default:
133
+ }
134
+ return false;
135
+ });
136
+ }
137
+
108
138
  export interface SelectInputProps<T = string> {
109
139
  name?: string;
110
140
  placeholder?: string;
@@ -175,7 +205,7 @@ function SelectInputClearButton({ className, onClick }: SelectInputClearButtonPr
175
205
  return (
176
206
  <button
177
207
  type="button"
178
- aria-label={intl.formatMessage(messages.ariaLabel)}
208
+ aria-label={intl.formatMessage(dateTriggerMessages.ariaLabel)}
179
209
  className={classNames(className, 'np-select-input-addon np-select-input-addon--interactive')}
180
210
  onClick={onClick}
181
211
  >
@@ -227,8 +257,9 @@ export function SelectInput<T = string>({
227
257
  }}
228
258
  >
229
259
  {({ disabled: uiDisabled, value }) => (
230
- <SelectInputHasValueContext.Provider value={value != null}>
260
+ <SelectInputItemCheckPaddingContext.Provider value={Boolean(filterable) || value != null}>
231
261
  <OptionsOverlay
262
+ placement="bottom-start"
232
263
  open={open}
233
264
  renderTrigger={({ ref, getInteractionProps }) => (
234
265
  <SelectInputTriggerButtonPropsContext.Provider
@@ -283,17 +314,19 @@ export function SelectInput<T = string>({
283
314
  listboxRef={listboxRef}
284
315
  />
285
316
  </OptionsOverlay>
286
- </SelectInputHasValueContext.Provider>
317
+ </SelectInputItemCheckPaddingContext.Provider>
287
318
  )}
288
319
  </ListboxBase>
289
320
  );
290
321
  }
291
322
 
292
- export type SelectInputTriggerButtonProps<T extends React.ComponentType | 'button' = 'button'> = {
293
- as?: T;
294
- } & React.ComponentPropsWithoutRef<T>;
323
+ type SelectInputTriggerButtonElementType = 'button' | React.ComponentType;
324
+
325
+ export type SelectInputTriggerButtonProps<
326
+ T extends SelectInputTriggerButtonElementType = 'button',
327
+ > = Merge<React.ComponentPropsWithoutRef<T>, { as?: T }>;
295
328
 
296
- export function SelectInputTriggerButton<T extends React.ComponentType | 'button' = 'button'>({
329
+ export function SelectInputTriggerButton<T extends SelectInputTriggerButtonElementType = 'button'>({
297
330
  as = 'button' as T,
298
331
  ...restProps
299
332
  }: SelectInputTriggerButtonProps<T>) {
@@ -336,9 +369,16 @@ const SelectInputOptionsContainer = forwardRef(function SelectInputOptionsContai
336
369
  ref={ref}
337
370
  onKeyDown={(event) => {
338
371
  // Prevent absorbing dismissal requests too early
339
- if (event.key !== 'Escape') {
340
- onKeyDown?.(event);
372
+ if (event.key === 'Escape') {
373
+ return;
341
374
  }
375
+
376
+ // Prevent confirmation close without an active item
377
+ if (event.key === 'Enter' && ariaActiveDescendant == null) {
378
+ return;
379
+ }
380
+
381
+ onKeyDown?.(event);
342
382
  }}
343
383
  {...restProps}
344
384
  />
@@ -354,11 +394,15 @@ interface SelectInputOptionsProps<T = string>
354
394
  function SelectInputOptions<T = string>({
355
395
  items,
356
396
  renderValue = wrapInFragment,
357
- filterable,
397
+ filterable = false,
358
398
  filterPlaceholder,
359
399
  searchInputRef,
360
400
  listboxRef,
361
401
  }: SelectInputOptionsProps<T>) {
402
+ const intl = useIntl();
403
+
404
+ const controllerRef = filterable ? searchInputRef : listboxRef;
405
+
362
406
  const [query, setQuery] = useState('');
363
407
  const needle = useMemo(() => {
364
408
  if (filterable) {
@@ -366,6 +410,7 @@ function SelectInputOptions<T = string>({
366
410
  }
367
411
  return undefined;
368
412
  }, [filterable, query]);
413
+ const empty = needle != null && filterSelectInputItems(items, needle).length === 0;
369
414
 
370
415
  const listboxContainerRef = useRef<HTMLDivElement>(null);
371
416
  useEffect(() => {
@@ -377,10 +422,10 @@ function SelectInputOptions<T = string>({
377
422
  }
378
423
  }, []);
379
424
 
425
+ const showStatus = empty;
426
+ const statusId = useId();
380
427
  const listboxId = useId();
381
428
 
382
- const controllerRef = filterable ? searchInputRef : listboxRef;
383
-
384
429
  return (
385
430
  <ListboxBase.Options
386
431
  as={SelectInputOptionsContainer}
@@ -404,6 +449,7 @@ function SelectInputOptions<T = string>({
404
449
  placeholder={filterPlaceholder}
405
450
  value={query}
406
451
  aria-controls={listboxId}
452
+ aria-describedby={showStatus ? statusId : undefined}
407
453
  onKeyDown={(event) => {
408
454
  // Prevent interfering with the matcher of Headless UI
409
455
  // https://mathiasbynens.be/notes/javascript-unicode#regex
@@ -426,6 +472,13 @@ function SelectInputOptions<T = string>({
426
472
  'np-select-input-listbox-container--has-group',
427
473
  )}
428
474
  >
475
+ {empty ? (
476
+ <div id={statusId} className="np-select-input-options-status">
477
+ <CrossCircle size={16} className="np-select-input-options-status-icon" />
478
+ {intl.formatMessage(messages.noResultsFound)}
479
+ </div>
480
+ ) : null}
481
+
429
482
  <div
430
483
  ref={listboxRef}
431
484
  id={listboxId}
@@ -434,7 +487,7 @@ function SelectInputOptions<T = string>({
434
487
  tabIndex={0}
435
488
  className="np-select-input-listbox"
436
489
  >
437
- {(needle == null ? items : dedupeSelectInputItems(items)).map((item, index) => (
490
+ {(needle != null ? dedupeSelectInputItems(items) : items).map((item, index) => (
438
491
  <SelectInputItemView
439
492
  // eslint-disable-next-line react/no-array-index-key
440
493
  key={index}
@@ -464,13 +517,7 @@ function SelectInputItemView<T = string>({
464
517
  }: SelectInputItemViewProps<T>) {
465
518
  switch (item.type) {
466
519
  case 'option': {
467
- if (
468
- item.value != null &&
469
- (!needle ||
470
- inferSearchableStrings(item.filterMatchers ?? item.value).some((haystack) =>
471
- haystack.includes(needle),
472
- ))
473
- ) {
520
+ if (item.value != null && (needle == null || filterSelectInputOptionItem(item, needle))) {
474
521
  return (
475
522
  <SelectInputOption value={item.value} disabled={item.disabled}>
476
523
  {renderValue(item.value, false)}
@@ -501,6 +548,7 @@ function SelectInputGroupItemView<T = string>({
501
548
  needle,
502
549
  }: SelectInputGroupItemViewProps<T>) {
503
550
  const headerId = useId();
551
+ const checkPadding = useSelectInputItemCheckPadding();
504
552
 
505
553
  return (
506
554
  // An empty container may be rendered when no options match `needle`
@@ -516,6 +564,7 @@ function SelectInputGroupItemView<T = string>({
516
564
  role="presentation"
517
565
  className="np-select-input-group-item-header np-text-title-group"
518
566
  >
567
+ {checkPadding ? <span className="np-select-input-option-check-placeholder" /> : null}
519
568
  {item.label}
520
569
  </header>
521
570
  ) : null}
@@ -539,24 +588,33 @@ interface SelectInputOptionProps<T = string> {
539
588
  }
540
589
 
541
590
  function SelectInputOption<T = string>({ value, disabled, children }: SelectInputOptionProps<T>) {
591
+ const checkPadding = useSelectInputItemCheckPadding();
592
+
542
593
  return (
543
594
  <ListboxBase.Option
544
595
  as="div"
545
596
  value={value}
546
597
  disabled={disabled}
547
- className={({ active, selected, disabled: uiDisabled }) =>
598
+ className={({ active, disabled: uiDisabled }) =>
548
599
  classNames(
549
600
  'np-select-input-option-container np-text-body-large',
550
601
  active && 'np-select-input-option-container--active',
551
- selected && 'np-select-input-option-container--selected',
552
602
  uiDisabled && 'np-select-input-option-container--disabled',
553
603
  )
554
604
  }
555
605
  >
556
606
  {({ selected }) => (
557
607
  <>
608
+ {checkPadding ? (
609
+ <Check
610
+ size={16}
611
+ className={classNames(
612
+ 'np-select-input-option-check',
613
+ !selected && 'np-select-input-option-check--not-selected',
614
+ )}
615
+ />
616
+ ) : null}
558
617
  <div className="np-select-input-option">{children}</div>
559
- {selected && <Check size={24} className={classNames('np-select-input-option-check')} />}
560
618
  </>
561
619
  )}
562
620
  </ListboxBase.Option>