<NME> utils.js
<BEF> import { getRange } from './dates';

/**
 * Returns a value no smaller than min and no larger than max.
 *
 * @param {*} value Value to return.
 * @param {*} min Minimum return value.
 * @param {*} max Maximum return value.
 */
export function between(value, min, max) {
  if (min && min > value) {
    return min;
  }
  if (max && max < value) {
    return max;
  }
  return value;
}

export function isValueWithinRange(value, range) {
  return range[0] <= value && range[1] >= value;
}

export function isRangeWithinRange(greaterRange, smallerRange) {
  return greaterRange[0] <= smallerRange[0] && greaterRange[1] >= smallerRange[1];
}

export function doRangesOverlap(range1, range2) {
  return isValueWithinRange(range1[0], range2) || isValueWithinRange(range1[1], range2);
}

function getRangeClassNames(valueRange, dateRange, baseClassName) {
  const isRange = doRangesOverlap(dateRange, valueRange);

  const classes = [];

  if (isRange) {
    classes.push(baseClassName);

    const isRangeStart = isValueWithinRange(valueRange[0], dateRange);
    const isRangeEnd = isValueWithinRange(valueRange[1], dateRange);

    if (isRangeStart) {
      classes.push(`${baseClassName}Start`);
    }

    if (isRangeEnd) {
      classes.push(`${baseClassName}End`);
    }

    if (isRangeStart && isRangeEnd) {
  return value;
};

export const getTileClasses = ({
  value, valueType, date, dateType, hover,
} = {}) => {

  if (!date) {
    return classes;
  }

  if (!Array.isArray(date) && !dateType) {
    throw new Error(
      'getTileClasses(): Unable to get tile activity classes because one or more required arguments were not passed.',
    );
  }

  const now = new Date();
  const dateRange = Array.isArray(date) ? date : getRange(dateType, date);

  if (isValueWithinRange(now, dateRange)) {
    classes.push(`${className}--now`);
  }

  if (!value) {
    return classes;
  }

  if (!Array.isArray(value) && !valueType) {
    throw new Error(
      'getTileClasses(): Unable to get tile activity classes because one or more required arguments were not passed.',
    );
  }

  const valueRange = Array.isArray(value) ? value : getRange(valueType, value);

  if (isRangeWithinRange(valueRange, dateRange)) {
    classes.push(`${className}--active`);
  } else if (doRangesOverlap(valueRange, dateRange)) {
    classes.push(`${className}--hasActive`);
  }
  ) {
    classes.push(`${className}--hover`);
  }

  if (isValueWithinRange(now, dateRange)) {
    classes.push(`${className}--now`);
  }

  return classes;
}

<MSG> fixes #83
<DFF> @@ -52,6 +52,10 @@ export const between = (value, min, max) => {
   return value;
 };
 
+const isEqual = (date1, date2) => {
+  return new Date(date1).getTime() === new Date(date2).getTime();
+}
+
 export const getTileClasses = ({
   value, valueType, date, dateType, hover,
 } = {}) => {
@@ -93,6 +97,12 @@ export const getTileClasses = ({
   ) {
     classes.push(`${className}--hover`);
   }
+  
+  if (isEqual(dateRange[0], valueRange[0])) {
+    classes.push(className + '--rangeStart')
+  } else if (isEqual(dateRange[1], valueRange[1])) {
+    classes.push(className + '--rangeEnd')
+  }
 
   if (isValueWithinRange(now, dateRange)) {
     classes.push(`${className}--now`);

{'addition_count': 10, 'commit_subject': 'fixes #83', 'deletion_count': 0, 'file_extension': '.js', 'lang': 'js', 'license': 'mit', 'repo_name': 'wojtekmaj/react-calendar'}