@transferwise/components 0.0.0-experimental-76c1faf → 0.0.0-experimental-4409807

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.
@@ -746,6 +746,7 @@ function SelectInputOptions<T = string>({
746
746
  }
747
747
  return undefined;
748
748
  }, [filterQuery, filterable]);
749
+
749
750
  useEffect(() => {
750
751
  if (needle) {
751
752
  // Ensure having an active option while filtering.
@@ -865,8 +866,33 @@ function SelectInputOptions<T = string>({
865
866
  setInitialRender(false);
866
867
  }, []);
867
868
 
869
+ const visibleOptionCount = useMemo(() => {
870
+ let count = 0;
871
+ for (const item of filteredItems) {
872
+ if (item.type === 'option') {
873
+ if (
874
+ item.value != null &&
875
+ (needle == null || selectInputOptionItemIncludesNeedle(item, needle))
876
+ ) {
877
+ count += 1;
878
+ }
879
+ } else if (item.type === 'group') {
880
+ for (const option of item.options) {
881
+ if (
882
+ option.value != null &&
883
+ (needle == null || selectInputOptionItemIncludesNeedle(option, needle))
884
+ ) {
885
+ count += 1;
886
+ }
887
+ }
888
+ }
889
+ }
890
+ return count;
891
+ }, [filteredItems, needle]);
892
+
868
893
  const showStatus = resultsEmpty;
869
894
  const statusId = useId();
895
+ const liveRegionId = useId();
870
896
  const listboxId = useId();
871
897
 
872
898
  const getItemNode = (index: number) => {
@@ -913,7 +939,7 @@ function SelectInputOptions<T = string>({
913
939
  className="np-select-input-options-container"
914
940
  onAriaActiveDescendantChange={(value: React.AriaAttributes['aria-activedescendant']) => {
915
941
  if (controllerRef.current != null) {
916
- if (!initialRender && value != null) {
942
+ if (!initialRender && value != null && needle == null) {
917
943
  controllerRef.current.setAttribute('aria-activedescendant', value);
918
944
  } else {
919
945
  controllerRef.current.removeAttribute('aria-activedescendant');
@@ -936,7 +962,11 @@ function SelectInputOptions<T = string>({
936
962
  aria-autocomplete="list"
937
963
  aria-expanded
938
964
  aria-controls={listboxId}
939
- aria-describedby={showStatus ? statusId : undefined}
965
+ aria-describedby={
966
+ [showStatus ? statusId : null, needle != null ? liveRegionId : null]
967
+ .filter(Boolean)
968
+ .join(' ') || undefined
969
+ }
940
970
  onKeyDown={(event) => {
941
971
  // Prevent interfering with the matcher of Headless UI
942
972
  // https://mathiasbynens.be/notes/javascript-unicode#regex
@@ -972,6 +1002,18 @@ function SelectInputOptions<T = string>({
972
1002
  </div>
973
1003
  ) : null}
974
1004
 
1005
+ <div
1006
+ id={liveRegionId}
1007
+ role="status"
1008
+ aria-live="polite"
1009
+ aria-atomic="true"
1010
+ className="sr-only"
1011
+ >
1012
+ {needle != null
1013
+ ? intl.formatMessage(messages.filteredResultsCount, { count: visibleOptionCount })
1014
+ : null}
1015
+ </div>
1016
+
975
1017
  <section
976
1018
  ref={listboxContainerRef}
977
1019
  tabIndex={-1}