{"mappings":"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","sources":["packages/react-aria/src/grid/useGridSelectionAnnouncement.ts"],"sourcesContent":["/*\n * Copyright 2022 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {announce} from '../live-announcer/LiveAnnouncer';\nimport {Collection, Key, Node, Selection} from '@react-types/shared';\n// @ts-ignore\nimport intlMessages from '../../intl/grid/*.json';\nimport {SelectionManager} from 'react-stately/private/selection/SelectionManager';\nimport {useCallback, useRef} from 'react';\nimport {useLocalizedStringFormatter} from '../i18n/useLocalizedStringFormatter';\nimport {useUpdateEffect} from '../utils/useUpdateEffect';\n\nexport interface GridSelectionAnnouncementProps {\n  /**\n   * A function that returns the text that should be announced by assistive technology when a row is added or removed from selection.\n   * @default (key) => state.collection.getItem(key)?.textValue\n   */\n  getRowText?: (key: Key) => string\n}\n\ninterface GridSelectionState<T> {\n  /** A collection of items in the grid. */\n  collection: Collection<Node<T>>,\n  /** A set of items that are disabled. */\n  disabledKeys: Set<Key>,\n  /** A selection manager to read and update multiple selection state. */\n  selectionManager: SelectionManager\n}\n\nexport function useGridSelectionAnnouncement<T>(props: GridSelectionAnnouncementProps, state: GridSelectionState<T>): void {\n  let {\n    getRowText = (key) => state.collection.getTextValue?.(key) ?? state.collection.getItem(key)?.textValue\n  } = props;\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/grid');\n\n  // Many screen readers do not announce when items in a grid are selected/deselected.\n  // We do this using an ARIA live region.\n  let selection = state.selectionManager.rawSelection;\n  let lastSelection = useRef(selection);\n  let announceSelectionChange = useCallback(() => {\n    if (!state.selectionManager.isFocused || selection === lastSelection.current) {\n      lastSelection.current = selection;\n\n      return;\n    }\n\n    let addedKeys = diffSelection(selection, lastSelection.current);\n    let removedKeys = diffSelection(lastSelection.current, selection);\n\n    // If adding or removing a single row from the selection, announce the name of that item.\n    let isReplace = state.selectionManager.selectionBehavior === 'replace';\n    let messages: string[] = [];\n\n    if ((state.selectionManager.selectedKeys.size === 1 && isReplace)) {\n      let firstKey = state.selectionManager.selectedKeys.keys().next().value;\n      if (firstKey != null && state.collection.getItem(firstKey)) {\n        let currentSelectionText = getRowText(firstKey);\n        if (currentSelectionText) {\n          messages.push(stringFormatter.format('selectedItem', {item: currentSelectionText}));\n        }\n      }\n    } else if (addedKeys.size === 1 && removedKeys.size === 0) {\n      let firstKey = addedKeys.keys().next().value;\n      if (firstKey != null) {\n        let addedText = getRowText(firstKey);\n        if (addedText) {\n          messages.push(stringFormatter.format('selectedItem', {item: addedText}));\n        }\n      }\n    } else if (removedKeys.size === 1 && addedKeys.size === 0) {\n      let firstKey = removedKeys.keys().next().value;\n      if (firstKey != null && state.collection.getItem(firstKey)) {\n        let removedText = getRowText(firstKey);\n        if (removedText) {\n          messages.push(stringFormatter.format('deselectedItem', {item: removedText}));\n        }\n      }\n    }\n\n    // Announce how many items are selected, except when selecting the first item.\n    if (state.selectionManager.selectionMode === 'multiple') {\n      if (messages.length === 0 || selection === 'all' || selection.size > 1 || lastSelection.current === 'all' || lastSelection.current?.size > 1) {\n        messages.push(selection === 'all'\n          ? stringFormatter.format('selectedAll')\n          : stringFormatter.format('selectedCount', {count: selection.size})\n        );\n      }\n    }\n\n    if (messages.length > 0) {\n      announce(messages.join(' '));\n    }\n\n    lastSelection.current = selection;\n  }, [\n    selection,\n    state.selectionManager.selectedKeys,\n    state.selectionManager.isFocused,\n    state.selectionManager.selectionBehavior,\n    state.selectionManager.selectionMode,\n    state.collection,\n    getRowText,\n    stringFormatter\n  ]);\n\n  // useUpdateEffect will handle using useEffectEvent, no need to stabilize anything on this end\n  useUpdateEffect(() => {\n    if (state.selectionManager.isFocused) {\n      announceSelectionChange();\n    } else {\n      // Wait a frame in case the collection is about to become focused (e.g. on mouse down).\n      let raf = requestAnimationFrame(announceSelectionChange);\n      return () => cancelAnimationFrame(raf);\n    }\n  }, [selection, state.selectionManager.isFocused]);\n}\n\nfunction diffSelection(a: Selection, b: Selection): Set<Key> {\n  let res = new Set<Key>();\n  if (a === 'all' || b === 'all') {\n    return res;\n  }\n\n  for (let key of a.keys()) {\n    if (!b.has(key)) {\n      res.add(key);\n    }\n  }\n\n  return res;\n}\n"],"names":[],"version":3,"file":"useGridSelectionAnnouncement.cjs.map"}