All files / src/composables useMultiSelectDisplay.js

100% Statements 34/34
100% Branches 33/33
100% Functions 8/8
100% Lines 33/33

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              47x 72x 72x                   48x   35x 53x 53x     35x 2x     33x   35x   47x 41x 41x   41x 28x     13x 7x     6x 3x 1x   2x 2x     3x 2x     1x     47x 31x   31x 28x     3x 3x     47x            
import { computed, unref } from 'vue';
 
export default function useMultiSelectDisplay(
  selectedValues,
  options,
  config = {},
) {
  const getConfig = () => {
    const configValue = unref(config);
    return {
      placeholder: configValue.placeholder || 'Select items',
      maxDisplay:
        configValue.maxDisplay !== undefined ? configValue.maxDisplay : 2,
      showCount:
        configValue.showCount !== undefined ? configValue.showCount : true,
      format: configValue.format || 'badge',
    };
  };
 
  const selectedLabels = computed(() => selectedValues.value
    .map((val) => {
      const option = options.value.find((opt) => {
        const optValue = opt.value || opt;
        return optValue === val;
      });
 
      if (!option) {
        return null;
      }
 
      return option.displayValue || option.label || option.value || option;
    })
    .filter((label) => label !== null));
 
  const displayText = computed(() => {
    const { placeholder, maxDisplay, format } = getConfig();
    const count = selectedLabels.value.length;
 
    if (count === 0) {
      return placeholder;
    }
 
    if (format === 'badge') {
      return placeholder;
    }
 
    if (format === 'inline') {
      if (count <= maxDisplay) {
        return selectedLabels.value.join(', ');
      }
      const visible = selectedLabels.value.slice(0, maxDisplay).join(', ');
      return `${visible} +${count - maxDisplay}`;
    }
 
    if (format === 'custom') {
      return count === 1 ? '1 item selected' : `${count} items selected`;
    }
 
    return placeholder;
  });
 
  const displayCount = computed(() => {
    const { showCount } = getConfig();
 
    if (!showCount) {
      return null;
    }
 
    const count = selectedLabels.value.length;
    return count > 0 ? count.toString() : null;
  });
 
  return {
    displayText,
    displayCount,
    selectedLabels,
  };
}