# All files / src/Thumbnail Thumbnail.hooks.tsx

100% Statements 45/45
85% Branches 34/40
100% Functions 1/1
100% Lines 35/35

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    896x
    6x
    6x
    6x

    6x

    6x

    6x
    67x
    67x
    67x
    67x
    67x
    67x
    67x
    67x
    67x

    67x
    67x

    67x

    67x
    67x

    67x

    67x
    67x

    67x
    67x
    67x
    67x
    67x
    67x

    67x
    67x
    67x

    67x

    67x

     import { useCheckbox } from '@react-aria/checkbox'
    import { useFocusRing } from '@react-aria/focus'
    import React, { useRef } from 'react'
    import { useToggleState } from 'react-stately'
    import { DivAttributes } from '../_utils/types'
    import { LayoutVariant, ThumbnailProps } from './Thumbnail.types'
    import { getIsFilePreviewableAsImage } from './Thumbnail.utils'

    const defaultSize = 'lg'

    export const useThumbnail = ({
      selected,
      disabled = false,
      clickable = true,
      focused = false,
      hasCaptionPlaceholder = false,
      src,
      filename: filename_,
      size = defaultSize,
      label = '',
      // @ts-ignore  Checkbox only
      name,
      caption = '',
      // @ts-ignore  Checkbox only
      onChange,
      // @ts-ignore  Checkbox only
      value,
      ...props
    }:
      | ThumbnailProps<'checkbox'>
      | ThumbnailProps<'figure'>
      | ThumbnailProps<undefined>) => {
      const a11yProps =
        props.role === 'figure'
          ? { as: 'figure' as React.ElementType }
          : { as: 'div' }
      const inputRef = useRef<HTMLInputElement>(null)
      const toggleState = useToggleState({
        defaultSelected: selected,
        onChange,
      })
      const layout: LayoutVariant = size === 'sm' ? 'row' : 'column'
      const isFile = src instanceof File
      const isImageURL = typeof src === 'string'
      const canPreviewFileAsImage = getIsFilePreviewableAsImage(src)
      const isFileOrNonPreviewableImage = isFile && !canPreviewFileAsImage
      const shouldUsePlaceholder = isFileOrNonPreviewableImage || !src
      const filename =
        filename_ ?? (isFileOrNonPreviewableImage ? (src as File).name : caption)
      const ariaLabel = label && caption ? `${label} ${caption}` : caption || label
      const { inputProps } = useCheckbox(
        { isSelected: selected, 'aria-label': ariaLabel, name, onChange, value },
        toggleState,
        inputRef
      )
      const { isFocusVisible, focusProps } = useFocusRing()

      return {
        alt: props.alt || props.alt === '' ? props.alt : caption || label,
        ...props,
        ...a11yProps,
        label,
        caption,
        selected: toggleState.isSelected,
        disabled,
        clickable,
        focused,
        isImageURL,
        hasCaptionPlaceholder,
        shouldUsePlaceholder,
        src,
        filename,
        size,
        layout,
        inputRef,
        inputProps,
        /**
         * Appeared 23-1-18 https://github.com/procore/core/pull/12250
         * Possible issue with types from React Aria during dependency update
         * > The inferred type of 'useThumbnail' cannot be named without a
         * > reference to '@react-aria/focus/node_modules/@react-types/shared'.
         * > This is likely not portable. A type annotation is necessary.
         */
        focusProps: focusProps as DivAttributes,
        isFocusVisible,
        toggleState,
      }
    }