From 8fc37fd3b36e6afe357a74942572421b2861a1c4 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 22 Sep 2025 13:31:21 -0700 Subject: [PATCH 1/4] chore: Update Picker multi-select text (#8901) * Update Picker multi-select text * Update RAC docs * Update S2 docs --- packages/@react-spectrum/s2/intl/ar-AE.json | 1 + packages/@react-spectrum/s2/intl/bg-BG.json | 1 + packages/@react-spectrum/s2/intl/cs-CZ.json | 1 + packages/@react-spectrum/s2/intl/da-DK.json | 1 + packages/@react-spectrum/s2/intl/de-DE.json | 1 + packages/@react-spectrum/s2/intl/el-GR.json | 1 + packages/@react-spectrum/s2/intl/en-US.json | 35 ++++++++++--------- packages/@react-spectrum/s2/intl/es-ES.json | 1 + packages/@react-spectrum/s2/intl/et-EE.json | 1 + packages/@react-spectrum/s2/intl/fi-FI.json | 1 + packages/@react-spectrum/s2/intl/fr-FR.json | 1 + packages/@react-spectrum/s2/intl/he-IL.json | 1 + packages/@react-spectrum/s2/intl/hr-HR.json | 1 + packages/@react-spectrum/s2/intl/hu-HU.json | 1 + packages/@react-spectrum/s2/intl/it-IT.json | 1 + packages/@react-spectrum/s2/intl/ja-JP.json | 1 + packages/@react-spectrum/s2/intl/ko-KR.json | 1 + packages/@react-spectrum/s2/intl/lt-LT.json | 1 + packages/@react-spectrum/s2/intl/lv-LV.json | 1 + packages/@react-spectrum/s2/intl/nb-NO.json | 1 + packages/@react-spectrum/s2/intl/nl-NL.json | 1 + packages/@react-spectrum/s2/intl/pl-PL.json | 1 + packages/@react-spectrum/s2/intl/pt-BR.json | 1 + packages/@react-spectrum/s2/intl/pt-PT.json | 1 + packages/@react-spectrum/s2/intl/ro-RO.json | 1 + packages/@react-spectrum/s2/intl/ru-RU.json | 1 + packages/@react-spectrum/s2/intl/sk-SK.json | 1 + packages/@react-spectrum/s2/intl/sl-SI.json | 1 + packages/@react-spectrum/s2/intl/sr-SP.json | 1 + packages/@react-spectrum/s2/intl/sv-SE.json | 1 + packages/@react-spectrum/s2/intl/tr-TR.json | 1 + packages/@react-spectrum/s2/intl/uk-UA.json | 1 + packages/@react-spectrum/s2/intl/zh-CN.json | 1 + packages/@react-spectrum/s2/intl/zh-TW.json | 1 + packages/@react-spectrum/s2/src/Picker.tsx | 8 +++-- .../dev/s2-docs/pages/react-aria/Select.mdx | 23 ++++++------ packages/dev/s2-docs/pages/s2/Picker.mdx | 24 +++++++------ .../react-aria-components/docs/Select.mdx | 6 ++-- starters/docs/src/Select.css | 5 ++- starters/tailwind/src/Select.tsx | 4 ++- 40 files changed, 92 insertions(+), 46 deletions(-) diff --git a/packages/@react-spectrum/s2/intl/ar-AE.json b/packages/@react-spectrum/s2/intl/ar-AE.json index 63c753e9578..da0c74bfa40 100644 --- a/packages/@react-spectrum/s2/intl/ar-AE.json +++ b/packages/@react-spectrum/s2/intl/ar-AE.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "نشاط جديد", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "تحديد…", + "picker.selectedCount": "{count, plural, =0 {لم يتم تحديد عناصر} one {# عنصر محدد} other {# عنصر محدد}}", "slider.maximum": "أقصى", "slider.minimum": "أدنى", "table.loading": "جارٍ التحميل...", diff --git a/packages/@react-spectrum/s2/intl/bg-BG.json b/packages/@react-spectrum/s2/intl/bg-BG.json index 71abfe418fb..57a159b530a 100644 --- a/packages/@react-spectrum/s2/intl/bg-BG.json +++ b/packages/@react-spectrum/s2/intl/bg-BG.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Нова дейност", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Изберете…", + "picker.selectedCount": "{count, plural, =0 {Няма избрани елементи} one {# избран елемент} other {# избрани елементи}}", "slider.maximum": "Максимум", "slider.minimum": "Минимум", "table.loading": "Зареждане...", diff --git a/packages/@react-spectrum/s2/intl/cs-CZ.json b/packages/@react-spectrum/s2/intl/cs-CZ.json index 9d7ef4dfb16..cafc3d9afbb 100644 --- a/packages/@react-spectrum/s2/intl/cs-CZ.json +++ b/packages/@react-spectrum/s2/intl/cs-CZ.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nová aktivita", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Vybrat…", + "picker.selectedCount": "{count, plural, =0 {Nevybrány žádné položky} one {Vybrána # položka} other {Vybráno # položek}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Načítání...", diff --git a/packages/@react-spectrum/s2/intl/da-DK.json b/packages/@react-spectrum/s2/intl/da-DK.json index d4987a27db4..796047f0199 100644 --- a/packages/@react-spectrum/s2/intl/da-DK.json +++ b/packages/@react-spectrum/s2/intl/da-DK.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Ny aktivitet", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Vælg…", + "picker.selectedCount": "{count, plural, =0 {Ingen elementer valgt} one {# element valgt} other {# elementer valgt}}", "slider.maximum": "Maksimum", "slider.minimum": "Minimum", "table.loading": "Indlæser...", diff --git a/packages/@react-spectrum/s2/intl/de-DE.json b/packages/@react-spectrum/s2/intl/de-DE.json index be126db8e9e..df797d68c2e 100644 --- a/packages/@react-spectrum/s2/intl/de-DE.json +++ b/packages/@react-spectrum/s2/intl/de-DE.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Neue Aktivität", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Auswählen…", + "picker.selectedCount": "{count, plural, =0 {Keine Elemente ausgewählt} one {# Element ausgewählt} other {# Elemente ausgewählt}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Laden...", diff --git a/packages/@react-spectrum/s2/intl/el-GR.json b/packages/@react-spectrum/s2/intl/el-GR.json index 9687cf911fd..a1381bae42d 100644 --- a/packages/@react-spectrum/s2/intl/el-GR.json +++ b/packages/@react-spectrum/s2/intl/el-GR.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Νέα δραστηριότητα", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Επιλογή…", + "picker.selectedCount": "{count, plural, =0 {Δεν επιλέχθηκαν στοιχεία} one {Επιλέχθηκε # στοιχείο} other {Επιλέχθηκαν # στοιχεία}}", "slider.maximum": "Μέγιστο", "slider.minimum": "Ελάχιστο", "table.loading": "Φόρτωση...", diff --git a/packages/@react-spectrum/s2/intl/en-US.json b/packages/@react-spectrum/s2/intl/en-US.json index e6379d040e7..b90516f839a 100644 --- a/packages/@react-spectrum/s2/intl/en-US.json +++ b/packages/@react-spectrum/s2/intl/en-US.json @@ -1,43 +1,44 @@ { + "actionbar.actions": "Actions", + "actionbar.actionsAvailable": "Actions available.", "actionbar.clearSelection": "Clear selection", "actionbar.selected": "{count, plural, =0 {None selected} other {# selected}}", "actionbar.selectedAll": "All selected", - "actionbar.actions": "Actions", - "actionbar.actionsAvailable": "Actions available.", + "breadcrumbs.more": "More items", "button.pending": "pending", "calendar.invalidSelection": "Selected {selectedCount, plural, one {date} other {dates}} unavailable.", - "contextualhelp.info": "Information", + "combobox.noResults": "No results", "contextualhelp.help": "Help", - "datepicker.time": "Time", - "datepicker.startTime": "Start time", + "contextualhelp.info": "Information", "datepicker.endTime": "End time", - "dialog.dismiss": "Dismiss", + "datepicker.startTime": "Start time", + "datepicker.time": "Time", "dialog.alert": "Alert", + "dialog.dismiss": "Dismiss", "dropzone.replaceMessage": "Drop file to replace", + "inlinealert.informative": "Information", "inlinealert.negative": "Error", "inlinealert.notice": "Warning", - "inlinealert.informative": "Information", "inlinealert.positive": "Success", - "label.(required)": "(required)", "label.(optional)": "(optional)", + "label.(required)": "(required)", "menu.moreActions": "More actions", + "notificationbadge.indicatorOnly": "New activity", + "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Select…", - "slider.minimum": "Minimum", + "picker.selectedCount": "{count, plural, =0 {No items selected} one {# item selected} other {# items selected}}", "slider.maximum": "Maximum", + "slider.minimum": "Minimum", "table.loading": "Loading…", "table.loadingMore": "Loading more…", + "table.resizeColumn": "Resize column", "table.sortAscending": "Sort Ascending", "table.sortDescending": "Sort Descending", - "table.resizeColumn": "Resize column", - "tag.showAllButtonLabel": "Show all ({tagCount, number})", - "tag.hideButtonLabel": "Show less", "tag.actions": "Actions", + "tag.hideButtonLabel": "Show less", "tag.noTags": "None", - "combobox.noResults": "No results", - "notificationbadge.plus": "{notifications}+", - "notificationbadge.indicatorOnly": "New activity", - "breadcrumbs.more": "More items", + "tag.showAllButtonLabel": "Show all ({tagCount, number})", "toast.clearAll": "Clear all", "toast.collapse": "Collapse", "toast.showAll": "Show all" -} \ No newline at end of file +} diff --git a/packages/@react-spectrum/s2/intl/es-ES.json b/packages/@react-spectrum/s2/intl/es-ES.json index 21b4364d820..2dfcc26a3f7 100644 --- a/packages/@react-spectrum/s2/intl/es-ES.json +++ b/packages/@react-spectrum/s2/intl/es-ES.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nueva actividad", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Seleccione…", + "picker.selectedCount": "{count, plural, =0 {Ningún elemento seleccionado} one {# elemento seleccionado} other {# elementos seleccionados}}", "slider.maximum": "Máximo", "slider.minimum": "Mínimo", "table.loading": "Cargando…", diff --git a/packages/@react-spectrum/s2/intl/et-EE.json b/packages/@react-spectrum/s2/intl/et-EE.json index 240a5b384db..0961526bc2c 100644 --- a/packages/@react-spectrum/s2/intl/et-EE.json +++ b/packages/@react-spectrum/s2/intl/et-EE.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Uus tegevus", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Valige…", + "picker.selectedCount": "{count, plural, =0 {Üksusi pole valitud} one {# üksus valitud} other {# üksust valitud}}", "slider.maximum": "Maksimaalne", "slider.minimum": "Minimaalne", "table.loading": "Laadimine...", diff --git a/packages/@react-spectrum/s2/intl/fi-FI.json b/packages/@react-spectrum/s2/intl/fi-FI.json index 28751379674..3c841a3fe38 100644 --- a/packages/@react-spectrum/s2/intl/fi-FI.json +++ b/packages/@react-spectrum/s2/intl/fi-FI.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Uusi toiminta", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Valitse…", + "picker.selectedCount": "{count, plural, =0 {Ei yhtään kohdetta valittu} one {# kohde valittu} other {# kohdetta valittu}}", "slider.maximum": "Maksimi", "slider.minimum": "Minimi", "table.loading": "Ladataan…", diff --git a/packages/@react-spectrum/s2/intl/fr-FR.json b/packages/@react-spectrum/s2/intl/fr-FR.json index 1769fcf84b3..e67742c73a6 100644 --- a/packages/@react-spectrum/s2/intl/fr-FR.json +++ b/packages/@react-spectrum/s2/intl/fr-FR.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nouvelle activité", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Sélectionner…", + "picker.selectedCount": "{count, plural, =0 {Aucun élément sélectionné} one {# élément sélectionné} other {# éléments sélectionnés}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Chargement...", diff --git a/packages/@react-spectrum/s2/intl/he-IL.json b/packages/@react-spectrum/s2/intl/he-IL.json index 4cbd06d0192..caae5e3ac7d 100644 --- a/packages/@react-spectrum/s2/intl/he-IL.json +++ b/packages/@react-spectrum/s2/intl/he-IL.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "פעילות חדשה", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "בחר…", + "picker.selectedCount": "{count, plural, =0 {לא נבחרו פריטים} one {פריט # נבחר} other {# פריטים נבחרו}}", "slider.maximum": "מקסימום", "slider.minimum": "מינימום", "table.loading": "טוען...", diff --git a/packages/@react-spectrum/s2/intl/hr-HR.json b/packages/@react-spectrum/s2/intl/hr-HR.json index 8e16ba6e24f..3b98a57760d 100644 --- a/packages/@react-spectrum/s2/intl/hr-HR.json +++ b/packages/@react-spectrum/s2/intl/hr-HR.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nova aktivnost", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Odaberite…", + "picker.selectedCount": "{count, plural, =0 {Nije odabrana nijedna stavka} one {Odabrana je # stavka} other {Odabrano je # stavki}}", "slider.maximum": "Najviše", "slider.minimum": "Najmanje", "table.loading": "Učitavam...", diff --git a/packages/@react-spectrum/s2/intl/hu-HU.json b/packages/@react-spectrum/s2/intl/hu-HU.json index 14cb6c573ed..3c2e6052c59 100644 --- a/packages/@react-spectrum/s2/intl/hu-HU.json +++ b/packages/@react-spectrum/s2/intl/hu-HU.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Új tevékenység", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Kiválasztás…", + "picker.selectedCount": "{count, plural, =0 {Egy elem sincs kijelölve} one {# elem kijelölve} other {# elem kijelölve}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Betöltés folyamatban…", diff --git a/packages/@react-spectrum/s2/intl/it-IT.json b/packages/@react-spectrum/s2/intl/it-IT.json index b33ff7b5918..c2995e56129 100644 --- a/packages/@react-spectrum/s2/intl/it-IT.json +++ b/packages/@react-spectrum/s2/intl/it-IT.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nuova attività", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Seleziona…", + "picker.selectedCount": "{count, plural, =0 {Nessun elemento selezionato} one {# elemento selezionato} other {# elementi selezionati}}", "slider.maximum": "Massimo", "slider.minimum": "Minimo", "table.loading": "Caricamento...", diff --git a/packages/@react-spectrum/s2/intl/ja-JP.json b/packages/@react-spectrum/s2/intl/ja-JP.json index f2e89bed5d7..e62d9e3cdc1 100644 --- a/packages/@react-spectrum/s2/intl/ja-JP.json +++ b/packages/@react-spectrum/s2/intl/ja-JP.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "新規アクティビティ", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "選択…", + "picker.selectedCount": "{count, plural, =0 {項目が選択されていません} one {# 項目を選択しました} other {# 項目を選択しました}}", "slider.maximum": "最大", "slider.minimum": "最小", "table.loading": "読み込み中...", diff --git a/packages/@react-spectrum/s2/intl/ko-KR.json b/packages/@react-spectrum/s2/intl/ko-KR.json index 82a0d88ba32..0b73bddd9ed 100644 --- a/packages/@react-spectrum/s2/intl/ko-KR.json +++ b/packages/@react-spectrum/s2/intl/ko-KR.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "새로운 활동", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "선택…", + "picker.selectedCount": "{count, plural, =0 {선택된 항목이 없습니다} one {#개 항목이 선택되었습니다} other {#개 항목이 선택되었습니다}}", "slider.maximum": "최대", "slider.minimum": "최소", "table.loading": "로드 중…", diff --git a/packages/@react-spectrum/s2/intl/lt-LT.json b/packages/@react-spectrum/s2/intl/lt-LT.json index fc56052e3cc..b51bce6380b 100644 --- a/packages/@react-spectrum/s2/intl/lt-LT.json +++ b/packages/@react-spectrum/s2/intl/lt-LT.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nauja veikla", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Pasirinkite…", + "picker.selectedCount": "{count, plural, =0 {Nepasirinktas nė vienas elementas} one {Pasirinktas # elementas} other {Pasirinkta elementų: #}}", "slider.maximum": "Daugiausia", "slider.minimum": "Mažiausia", "table.loading": "Įkeliama...", diff --git a/packages/@react-spectrum/s2/intl/lv-LV.json b/packages/@react-spectrum/s2/intl/lv-LV.json index e2f9bb316ad..e3f7a7ea231 100644 --- a/packages/@react-spectrum/s2/intl/lv-LV.json +++ b/packages/@react-spectrum/s2/intl/lv-LV.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Jauna aktivitāte", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Izvēlēties…", + "picker.selectedCount": "{count, plural, =0 {Nav atlasīts neviens vienums} one {Atlasīto vienumu skaits: #} other {Atlasīto vienumu skaits: #}}", "slider.maximum": "Maksimālā vērtība", "slider.minimum": "Minimālā vērtība", "table.loading": "Notiek ielāde...", diff --git a/packages/@react-spectrum/s2/intl/nb-NO.json b/packages/@react-spectrum/s2/intl/nb-NO.json index 226ce20af0f..74a143762ca 100644 --- a/packages/@react-spectrum/s2/intl/nb-NO.json +++ b/packages/@react-spectrum/s2/intl/nb-NO.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Ny aktivitet", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Velg …", + "picker.selectedCount": "{count, plural, =0 {Ingen elementer er valgt} one {# element er valgt} other {# elementer er valgt}}", "slider.maximum": "Maksimum", "slider.minimum": "Minimum", "table.loading": "Laster inn...", diff --git a/packages/@react-spectrum/s2/intl/nl-NL.json b/packages/@react-spectrum/s2/intl/nl-NL.json index 6fd3c0e362d..0db747b6997 100644 --- a/packages/@react-spectrum/s2/intl/nl-NL.json +++ b/packages/@react-spectrum/s2/intl/nl-NL.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nieuwe activiteit", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Selecteren…", + "picker.selectedCount": "{count, plural, =0 {Geen items geselecteerd} one {# item geselecteerd} other {# items geselecteerd}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Laden...", diff --git a/packages/@react-spectrum/s2/intl/pl-PL.json b/packages/@react-spectrum/s2/intl/pl-PL.json index 930f617b1ef..66d29db7d34 100644 --- a/packages/@react-spectrum/s2/intl/pl-PL.json +++ b/packages/@react-spectrum/s2/intl/pl-PL.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nowa aktywność", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Zaznacz…", + "picker.selectedCount": "{count, plural, =0 {Nie zaznaczono żadnych elementów} one {# zaznaczony element} other {# zaznaczonych elementów}}", "slider.maximum": "Maksimum", "slider.minimum": "Minimum", "table.loading": "Wczytywanie...", diff --git a/packages/@react-spectrum/s2/intl/pt-BR.json b/packages/@react-spectrum/s2/intl/pt-BR.json index a0c57db51d2..ac628a96544 100644 --- a/packages/@react-spectrum/s2/intl/pt-BR.json +++ b/packages/@react-spectrum/s2/intl/pt-BR.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nova atividade", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Selecionar…", + "picker.selectedCount": "{count, plural, =0 {Nenhum item selecionado} one {# item selecionado} other {# itens selecionados}}", "slider.maximum": "Máximo", "slider.minimum": "Mínimo", "table.loading": "Carregando...", diff --git a/packages/@react-spectrum/s2/intl/pt-PT.json b/packages/@react-spectrum/s2/intl/pt-PT.json index 5e8200ec1e4..4678701584b 100644 --- a/packages/@react-spectrum/s2/intl/pt-PT.json +++ b/packages/@react-spectrum/s2/intl/pt-PT.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nova atividade", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Selecionar…", + "picker.selectedCount": "{count, plural, =0 {Nenhum item selecionado} one {# item selecionado} other {# itens selecionados}}", "slider.maximum": "Máximo", "slider.minimum": "Mínimo", "table.loading": "A carregar...", diff --git a/packages/@react-spectrum/s2/intl/ro-RO.json b/packages/@react-spectrum/s2/intl/ro-RO.json index 145546503cd..df2a88359ce 100644 --- a/packages/@react-spectrum/s2/intl/ro-RO.json +++ b/packages/@react-spectrum/s2/intl/ro-RO.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Activitate nouă", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Selectați…", + "picker.selectedCount": "{count, plural, =0 {Niciun element selectat} one {# element selectat} other {# elemente selectate}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Se încarcă...", diff --git a/packages/@react-spectrum/s2/intl/ru-RU.json b/packages/@react-spectrum/s2/intl/ru-RU.json index eabe8666d8a..dd877691be5 100644 --- a/packages/@react-spectrum/s2/intl/ru-RU.json +++ b/packages/@react-spectrum/s2/intl/ru-RU.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Новая активность", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Выбрать…", + "picker.selectedCount": "{count, plural, =0 {Нет выбранных элементов} one {# элемент выбран} other {# элементов выбрано}}", "slider.maximum": "Максимум", "slider.minimum": "Минимум", "table.loading": "Загрузка...", diff --git a/packages/@react-spectrum/s2/intl/sk-SK.json b/packages/@react-spectrum/s2/intl/sk-SK.json index 5e564b9a9c2..35616f124e2 100644 --- a/packages/@react-spectrum/s2/intl/sk-SK.json +++ b/packages/@react-spectrum/s2/intl/sk-SK.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nová aktivita", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Vybrať…", + "picker.selectedCount": "{count, plural, =0 {Žiadne vybraté položky} one {# vybratá položka} other {Počet vybratých položiek:#}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Načítava sa...", diff --git a/packages/@react-spectrum/s2/intl/sl-SI.json b/packages/@react-spectrum/s2/intl/sl-SI.json index 65ad064cebf..83336132f92 100644 --- a/packages/@react-spectrum/s2/intl/sl-SI.json +++ b/packages/@react-spectrum/s2/intl/sl-SI.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nova dejavnost", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Izberite…", + "picker.selectedCount": "{count, plural, =0 {Noben element ni izbran} one {# element je izbran} other {# elementov je izbranih}}", "slider.maximum": "Največji", "slider.minimum": "Najmanj", "table.loading": "Nalaganje...", diff --git a/packages/@react-spectrum/s2/intl/sr-SP.json b/packages/@react-spectrum/s2/intl/sr-SP.json index 43c0d8100ec..cad130e5cb4 100644 --- a/packages/@react-spectrum/s2/intl/sr-SP.json +++ b/packages/@react-spectrum/s2/intl/sr-SP.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Nova aktivnost", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Izaberite...", + "picker.selectedCount": "{count, plural, =0 {Nije izabrana nijedna stavka} one {Izabrana je # stavka} other {Izabrano je # stavki}}", "slider.maximum": "Najviše", "slider.minimum": "Najmanje", "table.loading": "Učitavam...", diff --git a/packages/@react-spectrum/s2/intl/sv-SE.json b/packages/@react-spectrum/s2/intl/sv-SE.json index 1bf191fc9eb..a7d5a894872 100644 --- a/packages/@react-spectrum/s2/intl/sv-SE.json +++ b/packages/@react-spectrum/s2/intl/sv-SE.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Ny aktivitet", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Välj…", + "picker.selectedCount": "{count, plural, =0 {Inga markerade objekt} one {# markerat objekt} other {# markerade objekt}}", "slider.maximum": "Maximum", "slider.minimum": "Minimum", "table.loading": "Läser in...", diff --git a/packages/@react-spectrum/s2/intl/tr-TR.json b/packages/@react-spectrum/s2/intl/tr-TR.json index 1b563d0b56e..f9aa48680a0 100644 --- a/packages/@react-spectrum/s2/intl/tr-TR.json +++ b/packages/@react-spectrum/s2/intl/tr-TR.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Yeni etkinlik", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Seçin…", + "picker.selectedCount": "{count, plural, =0 {Hiçbir öge seçilmedi} one {# öge seçildi} other {# öge seçildi}}", "slider.maximum": "Maksimum", "slider.minimum": "Minimum", "table.loading": "Yükleniyor...", diff --git a/packages/@react-spectrum/s2/intl/uk-UA.json b/packages/@react-spectrum/s2/intl/uk-UA.json index 4000e3bc351..c78c03d9ce6 100644 --- a/packages/@react-spectrum/s2/intl/uk-UA.json +++ b/packages/@react-spectrum/s2/intl/uk-UA.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "Нова активність", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "Вибрати…", + "picker.selectedCount": "{count, plural, =0 {Жодних елементів не вибрано} one {# елемент вибрано} other {Вибрано елементів: #}}", "slider.maximum": "Максимум", "slider.minimum": "Мінімум", "table.loading": "Завантаження…", diff --git a/packages/@react-spectrum/s2/intl/zh-CN.json b/packages/@react-spectrum/s2/intl/zh-CN.json index 6ea8983b9d4..83fb0898fb1 100644 --- a/packages/@react-spectrum/s2/intl/zh-CN.json +++ b/packages/@react-spectrum/s2/intl/zh-CN.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "新活动", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "选择...", + "picker.selectedCount": "{count, plural, =0 {未选择项目} one {已选择 # 个项目} other {已选择 # 个项目}}", "slider.maximum": "最大", "slider.minimum": "最小", "table.loading": "正在加载...", diff --git a/packages/@react-spectrum/s2/intl/zh-TW.json b/packages/@react-spectrum/s2/intl/zh-TW.json index a112e4d3a76..e098b8c221e 100644 --- a/packages/@react-spectrum/s2/intl/zh-TW.json +++ b/packages/@react-spectrum/s2/intl/zh-TW.json @@ -26,6 +26,7 @@ "notificationbadge.indicatorOnly": "新活動", "notificationbadge.plus": "{notifications}+", "picker.placeholder": "選取…", + "picker.selectedCount": "{count, plural, =0 {未選取任何項目} one {已選取 # 個項目} other {已選取 # 個項目}}", "slider.maximum": "最大值", "slider.minimum": "最小值", "table.loading": "載入中…", diff --git a/packages/@react-spectrum/s2/src/Picker.tsx b/packages/@react-spectrum/s2/src/Picker.tsx index 21b9ecf27c3..312670de82d 100644 --- a/packages/@react-spectrum/s2/src/Picker.tsx +++ b/packages/@react-spectrum/s2/src/Picker.tsx @@ -479,6 +479,7 @@ const PickerButton = createHideableComponent(function PickerButton ( <> * {display: none;}')}> - {({selectedItems, defaultChildren, selectedText}) => { + {({selectedItems, defaultChildren}) => { return ( - {selectedItems.length <= 1 ? defaultChildren : {selectedText}} + {selectedItems.length <= 1 + ? defaultChildren + : {stringFormatter.format('picker.selectedCount', {count: selectedItems.length})} + } ); }} diff --git a/packages/dev/s2-docs/pages/react-aria/Select.mdx b/packages/dev/s2-docs/pages/react-aria/Select.mdx index 3a9f14b671a..1f364142b20 100644 --- a/packages/dev/s2-docs/pages/react-aria/Select.mdx +++ b/packages/dev/s2-docs/pages/react-aria/Select.mdx @@ -11,7 +11,7 @@ import Anatomy from 'react-aria-components/docs/SelectAnatomy.svg'; {docs.exports.Select.description} - ```tsx render docs={vanillaDocs.exports.Select} links={docs.links} props={['label', 'placeholder', 'isDisabled']} initialProps={{label: 'Favorite Animal'}} type="vanilla" files={["starters/docs/src/Select.tsx", "starters/docs/src/Select.css"]} + ```tsx render docs={vanillaDocs.exports.Select} links={docs.links} props={['label', 'placeholder', 'selectionMode', 'isDisabled']} initialProps={{label: 'Favorite Animal'}} type="vanilla" files={["starters/docs/src/Select.tsx", "starters/docs/src/Select.css"]} "use client"; import {Select, SelectItem} from 'vanilla-starter/Select'; @@ -25,7 +25,7 @@ import Anatomy from 'react-aria-components/docs/SelectAnatomy.svg'; ``` - ```tsx render docs={vanillaDocs.exports.Select} links={docs.links} props={['label', 'placeholder', 'isDisabled']} initialProps={{label: 'Favorite Animal'}} type="tailwind" files={["starters/tailwind/src/Select.tsx"]} + ```tsx render docs={vanillaDocs.exports.Select} links={docs.links} props={['label', 'placeholder', 'selectionMode', 'isDisabled']} initialProps={{label: 'Favorite Animal'}} type="tailwind" files={["starters/tailwind/src/Select.tsx"]} "use client"; import {Select, SelectItem} from 'tailwind-starter/Select'; @@ -135,26 +135,27 @@ function Example() { } ``` -## Selection +## Value -Use the `defaultSelectedKey` or `selectedKey` prop to set the selected item. The selected key corresponds to the `id` prop of an item. Items can be disabled with the `isDisabled` prop. See the [selection guide](selection.html?component=Select#single-selection) for more details. +Use the `defaultValue` or `value` prop to set the selected item. The value corresponds to the `id` prop of an item. When `selectionMode="multiple"`, `value` and `onChange` accept an array. Items can be disabled with the `isDisabled` prop. -```tsx render +```tsx render docs={docs.exports.Select} links={docs.links} props={['selectionMode']} wide "use client"; -import type {Key} from 'react-aria-components'; import {Select, SelectItem} from 'vanilla-starter/Select'; import {useState} from 'react'; -function Example() { - let [animal, setAnimal] = useState("bison"); +function Example(props) { + let [animal, setAnimal] = useState("bison"); return (
-

Current selection: {animal}

+
Current selection: {JSON.stringify(animal)}
); } diff --git a/packages/dev/s2-docs/pages/s2/Picker.mdx b/packages/dev/s2-docs/pages/s2/Picker.mdx index 329dedfd2f1..9199d6e1fbd 100644 --- a/packages/dev/s2-docs/pages/s2/Picker.mdx +++ b/packages/dev/s2-docs/pages/s2/Picker.mdx @@ -8,7 +8,7 @@ import docs from 'docs:@react-spectrum/s2'; {docs.exports.Picker.description} -```tsx render docs={docs.exports.Picker} links={docs.links} props={['label', 'size', 'labelPosition', 'description', 'contextualHelp', 'isQuiet', 'isDisabled']} initialProps={{label: 'Ice cream flavor'}} type="s2" +```tsx render docs={docs.exports.Picker} links={docs.links} props={['label', 'selectionMode', 'size', 'labelPosition', 'description', 'contextualHelp', 'isQuiet', 'isDisabled']} initialProps={{label: 'Ice cream flavor'}} type="s2" import {Picker, PickerItem} from '@react-spectrum/s2'; @@ -62,7 +62,7 @@ import Comment from '@react-spectrum/s2/icons/Comment'; import Edit from '@react-spectrum/s2/icons/Edit'; import UserSettings from '@react-spectrum/s2/icons/UserSettings'; - + {/*- begin highlight -*/} @@ -179,25 +179,27 @@ import {Picker, PickerItem} from '@react-spectrum/s2'; ``` -## Selection +## Value -Use the `defaultSelectedKey` or `selectedKey` prop to set the selected item. The selected key corresponds to the `id` prop of an item. Items can be disabled with the `isDisabled` prop. See the [selection guide](selection.html?component=Picker#single-selection) for more details. +Use the `defaultValue` or `value` prop to set the selected item. The value corresponds to the `id` prop of an item. When `selectionMode="multiple"`, `value` and `onChange` accept an array. Items can be disabled with the `isDisabled` prop. -```tsx render +```tsx render docs={docs.exports.Picker} links={docs.links} props={['selectionMode']} wide "use client"; -import {Picker, PickerItem, type Key} from '@react-spectrum/s2'; +import {Picker, PickerItem} from '@react-spectrum/s2'; import {useState} from 'react'; -function Example() { - let [animal, setAnimal] = useState("bison"); +function Example(props) { + let [animal, setAnimal] = useState("bison"); return (
Koala @@ -207,7 +209,7 @@ function Example() { Bison Skunk -

Current selection: {animal}

+
Current selection: {JSON.stringify(animal)}
); } diff --git a/packages/react-aria-components/docs/Select.mdx b/packages/react-aria-components/docs/Select.mdx index 34ab4cbf007..1fbab7bb376 100644 --- a/packages/react-aria-components/docs/Select.mdx +++ b/packages/react-aria-components/docs/Select.mdx @@ -1221,12 +1221,12 @@ function FieldGroup({title, children, isDisabled}: FieldGroupProps) { } - + Draft Published Deleted - + John Emma Tim @@ -1298,7 +1298,7 @@ function SelectClearButton() { // Don't inherit behavior from Select. slot={null} style={{fontSize: 'small', marginTop: 6, padding: 4}} - onPress={() => state?.setSelectedKey(null)}> + onPress={() => state?.setValue(null)}> Clear ); diff --git a/starters/docs/src/Select.css b/starters/docs/src/Select.css index 940ca7f1c96..8efe89a5e7a 100644 --- a/starters/docs/src/Select.css +++ b/starters/docs/src/Select.css @@ -37,8 +37,11 @@ } .react-aria-SelectValue { - flex: 1 0 auto; + flex: 1; text-align: start; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; &[data-placeholder] { font-style: italic; diff --git a/starters/tailwind/src/Select.tsx b/starters/tailwind/src/Select.tsx index 0b9fde25698..084b9217d1b 100644 --- a/starters/tailwind/src/Select.tsx +++ b/starters/tailwind/src/Select.tsx @@ -42,7 +42,9 @@ export function Select( {label && } {description && {description}} From c12a3b4ebbe4e963cf701fface23822efd354972 Mon Sep 17 00:00:00 2001 From: Devon Govett Date: Mon, 22 Sep 2025 13:41:10 -0700 Subject: [PATCH 2/4] feat: Add support for animated selection indicators (#8876) * feat: Add support for animated selection indicators * Add SelectionIndicator support for all other selectable components --- .../s2/src/SegmentedControl.tsx | 59 ++---- packages/@react-spectrum/s2/src/Tabs.tsx | 103 ++++------ .../dev/s2-docs/pages/react-aria/GridList.mdx | 4 +- .../dev/s2-docs/pages/react-aria/ListBox.mdx | 3 +- .../dev/s2-docs/pages/react-aria/Menu.mdx | 3 +- .../s2-docs/pages/react-aria/RadioGroup.mdx | 6 +- .../pages/react-aria/SegmentedControl.css | 51 +++++ .../pages/react-aria/SelectionIndicator.css | 39 ++++ .../dev/s2-docs/pages/react-aria/Table.mdx | 6 +- .../dev/s2-docs/pages/react-aria/Tabs.mdx | 16 +- .../dev/s2-docs/pages/react-aria/TagGroup.mdx | 3 +- .../pages/react-aria/ToggleButtonGroup.mdx | 37 +++- .../dev/s2-docs/pages/react-aria/Tree.mdx | 4 +- .../s2-docs/pages/react-aria/selection.mdx | 31 +++ packages/dev/s2-docs/src/StateTable.tsx | 9 +- .../react-aria-components/docs/GridList.mdx | 4 +- .../react-aria-components/docs/ListBox.mdx | 3 +- packages/react-aria-components/docs/Menu.mdx | 3 +- .../react-aria-components/docs/RadioGroup.mdx | 6 +- packages/react-aria-components/docs/Table.mdx | 6 +- packages/react-aria-components/docs/Tabs.mdx | 121 ++++++++---- .../react-aria-components/docs/TagGroup.mdx | 3 +- .../docs/ToggleButtonGroup.mdx | 94 ++++++++- packages/react-aria-components/docs/Tree.mdx | 4 +- .../react-aria-components/src/GridList.tsx | 17 +- .../react-aria-components/src/ListBox.tsx | 17 +- packages/react-aria-components/src/Menu.tsx | 15 +- .../react-aria-components/src/RadioGroup.tsx | 10 +- .../src/SelectionIndicator.tsx | 40 ++++ .../src/SharedElementTransition.tsx | 185 ++++++++++++++++++ packages/react-aria-components/src/Table.tsx | 15 +- packages/react-aria-components/src/Tabs.tsx | 10 +- .../react-aria-components/src/TagGroup.tsx | 13 +- .../src/ToggleButton.tsx | 7 +- .../src/ToggleButtonGroup.tsx | 5 +- packages/react-aria-components/src/Tree.tsx | 17 +- packages/react-aria-components/src/index.ts | 4 + starters/docs/src/Tabs.css | 53 +++-- starters/docs/src/Tabs.tsx | 14 +- starters/tailwind/src/Tabs.tsx | 14 +- 40 files changed, 799 insertions(+), 255 deletions(-) create mode 100644 packages/dev/s2-docs/pages/react-aria/SegmentedControl.css create mode 100644 packages/dev/s2-docs/pages/react-aria/SelectionIndicator.css create mode 100644 packages/react-aria-components/src/SelectionIndicator.tsx create mode 100644 packages/react-aria-components/src/SharedElementTransition.tsx diff --git a/packages/@react-spectrum/s2/src/SegmentedControl.tsx b/packages/@react-spectrum/s2/src/SegmentedControl.tsx index de31da5bde6..0dafd0cc08d 100644 --- a/packages/@react-spectrum/s2/src/SegmentedControl.tsx +++ b/packages/@react-spectrum/s2/src/SegmentedControl.tsx @@ -13,13 +13,13 @@ import {AriaLabelingProps, DOMRef, DOMRefValue, FocusableRef, Key} from '@react-types/shared'; import {baseColor, focusRing, style} from '../style' with {type: 'macro'}; import {centerBaseline} from './CenterBaseline'; -import {ContextValue, DEFAULT_SLOT, Provider, TextContext as RACTextContext, SlotProps, ToggleButton, ToggleButtonGroup, ToggleButtonRenderProps, ToggleGroupStateContext} from 'react-aria-components'; +import {ContextValue, DEFAULT_SLOT, Provider, TextContext as RACTextContext, SelectionIndicator, SlotProps, ToggleButton, ToggleButtonGroup, ToggleButtonRenderProps, ToggleGroupStateContext} from 'react-aria-components'; import {control, getAllowedOverrides, StyleProps} from './style-utils' with {type: 'macro'}; -import {createContext, forwardRef, ReactNode, RefObject, useCallback, useContext, useRef} from 'react'; +import {createContext, forwardRef, ReactNode, useCallback, useContext, useRef} from 'react'; import {IconContext} from './Icon'; import {pressScale} from './pressScale'; import {Text, TextContext} from './Content'; -import {useDOMRef, useFocusableRef, useMediaQuery} from '@react-spectrum/utils'; +import {useDOMRef, useFocusableRef} from '@react-spectrum/utils'; import {useLayoutEffect} from '@react-aria/utils'; import {useSpectrumContextProps} from './useSpectrumContextProps'; @@ -113,6 +113,13 @@ const slider = style<{isDisabled: boolean}>({ left: 0, width: 'full', height: 'full', + contain: 'strict', + transition: { + default: '[translate,width]', + '@media (prefers-reduced-motion: reduce)': 'none' + }, + transitionDuration: 200, + transitionTimingFunction: 'out', position: 'absolute', boxSizing: 'border-box', borderStyle: 'solid', @@ -130,8 +137,6 @@ const slider = style<{isDisabled: boolean}>({ interface InternalSegmentedControlContextProps { register?: (value: Key, isDisabled?: boolean) => void, - prevRef?: RefObject, - currentSelectedRef?: RefObject, isJustified?: boolean } @@ -139,8 +144,6 @@ interface DefaultSelectionTrackProps { defaultValue?: Key | null, value?: Key | null, children: ReactNode, - prevRef: RefObject, - currentSelectedRef: RefObject, isJustified?: boolean } @@ -158,14 +161,7 @@ export const SegmentedControl = /*#__PURE__*/ forwardRef(function SegmentedContr } = props; let domRef = useDOMRef(ref); - let prevRef = useRef(null); - let currentSelectedRef = useRef(null); - let onChange = (values: Set) => { - if (currentSelectedRef.current) { - prevRef.current = currentSelectedRef?.current.getBoundingClientRect(); - } - if (onSelectionChange) { let firstKey = values.values().next().value; if (firstKey != null) { @@ -186,7 +182,7 @@ export const SegmentedControl = /*#__PURE__*/ forwardRef(function SegmentedContr onSelectionChange={onChange} className={(props.UNSAFE_className || '') + segmentedControl(null, props.styles)} aria-label={props['aria-label']}> - + {props.children} @@ -209,7 +205,7 @@ function DefaultSelectionTracker(props: DefaultSelectionTrackProps) { return ( {props.children} @@ -222,46 +218,21 @@ function DefaultSelectionTracker(props: DefaultSelectionTrackProps) { export const SegmentedControlItem = /*#__PURE__*/ forwardRef(function SegmentedControlItem(props: SegmentedControlItemProps, ref: FocusableRef) { let domRef = useFocusableRef(ref); let divRef = useRef(null); - let {register, prevRef, currentSelectedRef, isJustified} = useContext(InternalSegmentedControlContext); - let state = useContext(ToggleGroupStateContext); - let isSelected = state?.selectedKeys.has(props.id); - // do not apply animation if a user has the prefers-reduced-motion setting - let reduceMotion = useMediaQuery('(prefers-reduced-motion: reduce)'); + let {register, isJustified} = useContext(InternalSegmentedControlContext); useLayoutEffect(() => { register?.(props.id); }, [register, props.id]); - useLayoutEffect(() => { - if (isSelected && prevRef?.current && currentSelectedRef?.current && !reduceMotion) { - let currentItem = currentSelectedRef?.current.getBoundingClientRect(); - - let deltaX = prevRef?.current.left - currentItem?.left; - - currentSelectedRef.current.animate( - [ - {transform: `translateX(${deltaX}px)`, width: `${prevRef?.current.width}px`}, - {transform: 'translateX(0px)', width: `${currentItem.width}px`} - ], - { - duration: 200, - easing: 'ease-out' - } - ); - - prevRef.current = null; - } - }, [isSelected, reduceMotion, prevRef, currentSelectedRef]); - return ( (props.UNSAFE_className || '') + controlItem({...renderProps, isJustified}, props.styles)} > - {({isSelected, isPressed, isDisabled}) => ( + {({isPressed, isDisabled}) => ( <> - {isSelected &&
} + , DOMRefValue>>(null); const InternalTabsContext = createContext & { tablistRef?: RefObject, - prevRef?: RefObject, selectedKey?: Key | null }>({}); @@ -133,14 +133,6 @@ export const Tabs = forwardRef(function Tabs(props: TabsProps, ref: DOMRef(null); - let prevRef = useRef(null); - - let onChange = useEffectEvent((val: Key) => { - if (tablistRef.current) { - prevRef.current = tablistRef.current.querySelector('[role=tab][data-selected=true]')?.getBoundingClientRect() ?? null; - } - setValue(val); - }); return ( )} @@ -294,6 +285,13 @@ const selectedIndicator = style<{isDisabled: boolean, orientation?: Orientation} vertical: '[2px]' } }, + contain: 'strict', + transition: { + default: '[translate,width,height]', + '@media (prefers-reduced-motion: reduce)': 'none' + }, + transitionDuration: 200, + transitionTimingFunction: 'out', bottom: { default: 0 }, @@ -374,7 +372,7 @@ const icon = style({ }); export function Tab(props: TabProps): ReactNode { - let {density, orientation, labelBehavior, prevRef} = useContext(InternalTabsContext) ?? {}; + let {density, orientation, labelBehavior} = useContext(InternalTabsContext) ?? {}; let contentId = useId(); let ariaLabelledBy = props['aria-labelledby'] || ''; @@ -390,7 +388,6 @@ export function Tab(props: TabProps): ReactNode { {({ // @ts-ignore isMenu, - isSelected, isDisabled }) => { if (isMenu) { @@ -417,10 +414,8 @@ export function Tab(props: TabProps): ReactNode { }] ]}> + isDisabled={isDisabled}> {typeof props.children === 'string' ? {props.children} : props.children} @@ -431,53 +426,17 @@ export function Tab(props: TabProps): ReactNode { ); } -function TabInner({isSelected, isDisabled, orientation, children, prevRef}: { - isSelected: boolean, +function TabInner({isDisabled, orientation, children}: { isDisabled: boolean, orientation: Orientation, - children: ReactNode, - prevRef?: RefObject + children: ReactNode }) { - let reduceMotion = useMediaQuery('(prefers-reduced-motion: reduce)'); let ref = useRef(null); - - useLayoutEffect(() => { - if (isSelected && prevRef?.current && ref?.current && !reduceMotion) { - let currentItem = ref?.current.getBoundingClientRect(); - - if (orientation === 'horizontal') { - let deltaX = prevRef.current.left - currentItem.left; - ref.current.animate( - [ - {transform: `translateX(${deltaX}px)`, width: `${prevRef.current.width}px`}, - {transform: 'translateX(0px)', width: '100%'} - ], - { - duration: 200, - easing: 'ease-out' - } - ); - } else { - let deltaY = prevRef.current.top - currentItem.top; - ref.current.animate( - [ - {transform: `translateY(${deltaY}px)`, height: `${prevRef.current.height}px`}, - {transform: 'translateY(0px)', height: '100%'} - ], - { - duration: 200, - easing: 'ease-out' - } - ); - } - - prevRef.current = null; - } - }, [isSelected, reduceMotion, prevRef, orientation]); + let isHidden = useContext(HiddenTabsContext); return ( <> - {isSelected &&
} + {!isHidden && } {children} ); @@ -549,6 +508,8 @@ function isEveryTabDisabled(collection: Collection> | undefined, disa return false; } +const HiddenTabsContext = createContext(false); + let HiddenTabs = function (props: { listRef: RefObject, items: Array>, @@ -573,18 +534,20 @@ let HiddenTabs = function (props: { overflow: 'hidden', opacity: 0 })}> - {items.map((item) => { - // pull off individual props as an allow list, don't want refs or other props getting through - return ( -
- {item.props.children({size, density})} -
- ); - })} + + {items.map((item) => { + // pull off individual props as an allow list, don't want refs or other props getting through + return ( +
+ {item.props.children({size, density})} +
+ ); + })} +
); }; diff --git a/packages/dev/s2-docs/pages/react-aria/GridList.mdx b/packages/dev/s2-docs/pages/react-aria/GridList.mdx index 7fcb080411e..894d2be8efb 100644 --- a/packages/dev/s2-docs/pages/react-aria/GridList.mdx +++ b/packages/dev/s2-docs/pages/react-aria/GridList.mdx @@ -263,11 +263,11 @@ function Example() { -```tsx links={{GridList: '#gridlist', GridListItem: '#gridlistitem', GridListLoadMoreItem: '#gridlistloadmoreitem', Button: 'Button.html', Checkbox: 'Checkbox.html'}} +```tsx links={{GridList: '#gridlist', GridListItem: '#gridlistitem', GridListLoadMoreItem: '#gridlistloadmoreitem', Button: 'Button.html', Checkbox: 'Checkbox.html', SelectionIndicator: 'selection.html#animated-selectionindicator'}}