All files / src/utils attribute.js

0% Statements 0/47
0% Branches 0/48
0% Functions 0/12
0% Lines 0/31
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                                                                                                                                                     
import DateInfo from './dateInfo';
import defaults from './defaults';
import { mixinOptionalProps, arrayHasItems } from './helpers';
import { isArray } from './typeCheckers';
 
const Attribute = (config) => {
  if (!config) return null;
  if (config.isAttribute) return config;
  if (config.dates && !isArray(config.dates)) config.dates = [config.dates];
  if (config.excludeDates && !isArray(config.excludeDates)) config.excludeDates = [config.excludeDates];
  const hasDates = arrayHasItems(config.dates);
  const hasExcludeDates = arrayHasItems(config.excludeDates);
  const dates =
    (
      (hasDates && config.dates) || // Use provided dates if they have items
      (hasExcludeDates && [{}]) ||  // Use infinite range if exclude dates were provided
      []                            // Use just an empty array
    )
    .map(d => (d.isDateInfo ? d : DateInfo(d, config.order)));
  const excludeDates =
    (
      (hasExcludeDates && config.excludeDates) ||
      []
    )
    .map(d => (d.isDateInfo ? d : DateInfo(d, config.order)));
  const isComplex = dates.some(d => d.isComplex);
  const attr = {
    isAttribute: true,
    key: config.key || 'guid',
    order: config.order || 0,
    dates,
    excludeDates,
    isComplex,
    // Any date partly intersects with given date
    intersectsDate: (date) => {
      const dateInfo = DateInfo(date);
      const matchDate = dates.find(d => d.intersects(dateInfo));
      if (!matchDate || !hasExcludeDates) return matchDate;
      const matchExDate = excludeDates.find(ed => ed.includes(dateInfo));
      return matchExDate ? false : matchDate;
    },
    // Accepts: DayInfo object
    // Returns: First attribute date or date range that occurs on given day.
    includesDay: dayInfo => dates
      .map(d => d.includesDay(dayInfo))
      .find((d) => {
        // Date doesn't match
        if (!d) return null;
        // No exclude dates to check - just return first match
        if (!hasExcludeDates) return d;
        // Return date if it isn't part of the excluded dates
        return excludeDates.find(ed => ed.includesDay(dayInfo)) ? false : d;
      }),
  };
  mixinOptionalProps(config, attr, [
    { name: 'highlight', mixin: defaults.highlight },
    { name: 'highlightCaps', mixin: defaults.highlightCaps },
    { name: 'dot', mixin: defaults.dot },
    { name: 'dotCaps' },
    { name: 'bar', mixin: defaults.bar },
    { name: 'barCaps' },
    { name: 'contentStyle' },
    { name: 'contentStyleCaps' },
    { name: 'contentHoverStyle' },
    { name: 'popover' },
    { name: 'customData' },
  ]);
  // Do some cleanup configuration for highlights
  if (attr.highlight && !attr.highlight.borderRadius) attr.highlight.borderRadius = attr.highlight.height;
  // Return the attribute
  return attr;
};
 
export default Attribute;