lodash-es#range TypeScript Examples

The following examples show how to use lodash-es#range. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: PageSelector.tsx    From UUI with MIT License 6 votes vote down vote up
PageSelector = UUIFunctionComponent({
  name: 'PageSelector',
  nodes: {
    Root: 'div',
    Select: HTMLSelect,
  },
  propTypes: PageSelectorPropTypes,
}, (props: PageSelectorFeatureProps, { nodes }) => {
  const { Root, Select } = nodes

  const context = useContext(PaginationContext)
  if (!context) {
    console.warn('[UUI] please use <PageSelector> in <Pagination>')
    return <></>
  }
  const { pagination, loading } = context

  const pageNumbers = range(1, pagination.totalPage+1)

  return (
    <Root>
      <Select
        disabled={loading}
        options={pageNumbers.map((i) => {
          return {
            label: props.labelRender ? props.labelRender(i, pagination.totalPage) : `${i} / ${pagination.totalPage}`,
            value: i,
          }
        })}
        value={pagination.currentPage}
        onChange={(value) => pagination.toNthPage(value)}
      />
    </Root>
  )
})
Example #2
Source File: Layout.stories.tsx    From UUI with MIT License 6 votes vote down vote up
Layout2 = () => {
  return (
    <div className="w-full" style={{ height: 600 }}>
      <Layout>
        <Layout.Nav className="bg-red-500">
          {range(1, 100).map((i) => {
            return <div key={i}>nav item {i}</div>
          })}
        </Layout.Nav>
        <Layout.Main className="bg-green-500">
          {range(1, 100).map((i) => {
            return <div key={i}>content item {i}</div>
          })}
        </Layout.Main>
      </Layout>
    </div>
  )
}
Example #3
Source File: PageList.tsx    From UUI with MIT License 5 votes vote down vote up
getEllipsisPageData = (currentPage: number, pageCount: number) => {
  const delta = (() => {
    if (pageCount <= 7) {
      // delta === 7: [1 2 3 4 5 6 7]
      return 7
    } else {
      // delta === 2: [1 ... 4 5 6 ... 10]
      // delta === 4: [1 2 3 4 5 ... 10]
      return currentPage > 4 && currentPage < pageCount - 3 ? 2 : 4
    }
  })()

  const _range = {
    start: Math.round(currentPage - delta / 2),
    end: Math.round(currentPage + delta / 2),
  }

  if (_range.start - 1 === 1 || _range.end + 1 === pageCount) {
    _range.start += 1
    _range.end += 1
  }

  let pages: any = currentPage > delta
    ? range(Math.min(_range.start, pageCount - delta), Math.min(_range.end, pageCount) + 1)
    : range(1, Math.min(pageCount, delta + 1) + 1)

  const withDots = (value: any, pair: any[]) => (pages.length + 1 !== pageCount ? pair : [value])

  if (pages[0] !== 1) {
    pages = withDots(1, [1, '...']).concat(pages)
  }

  if (pages[pages.length - 1] < pageCount) {
    pages = pages.concat(withDots(pageCount, ['...', pageCount]))
  }

  const data: {
    page: number;
    title: string;
    type: 'page' | 'ellipsis' | 'active';
  }[] = pages.map((i: any) => {
    if (i === '...') {
      return {
        page: -1,
        title: String(i),
        type: 'ellipsis',
      }
    } else {
      return {
        page: i,
        title: String(i),
        type: currentPage === i ? 'active' : 'page',
      }
    }
  })

  return data
}
Example #4
Source File: difference.spec.ts    From s-libs with MIT License 5 votes vote down vote up
describe('difference()', () => {
  //
  // stolen from https://github.com/lodash/lodash
  //

  it('should return the difference of two arrays', () => {
    expect(difference([2, 1], [2, 3])).toEqual([1]);
  });

  it('should return the difference of multiple arrays', () => {
    expect(difference([2, 1, 2, 3], [3, 4], [3, 2])).toEqual([1]);
  });

  it('should match `NaN`', () => {
    expect(difference([1, NaN, 3], [NaN, 5, NaN])).toEqual([1, 3]);
  });

  it('should work with large arrays', () => {
    const array1: any[] = range(201);
    const array2: any[] = range(200);
    const a = {};
    const b = {};
    const c = {};
    array1.push(a, b, c);
    array2.push(b, c, a);

    expect(difference(array1, array2)).toEqual([200]);
  });

  it('should work with large arrays of `NaN`', () => {
    const largeArray = times(200, () => NaN);
    expect(difference([1, NaN, 3], largeArray)).toEqual([1, 3]);
  });

  it('should work with large arrays of objects', () => {
    const object1 = {};
    const object2 = {};
    const largeArray = times(200, () => object1);

    expect(difference([object1, object2], largeArray)).toEqual([object2]);
  });

  it('should return an array', () => {
    const array = [1, 2, 3];
    const actual = difference(array);

    expect(actual).toEqual(jasmine.any(Array));
    expect(actual).not.toBe(array);
  });
});
Example #5
Source File: intersection.spec.ts    From s-libs with MIT License 5 votes vote down vote up
describe('intersection()', () => {
  it('works with null and undefined', () => {
    const array = [0, 1, null, 3];
    expect(intersection(array, null)).toEqual([]);
    expect(intersection(array, undefined)).toEqual([]);
    expect(intersection(null, array)).toEqual([]);
    expect(intersection(undefined, array)).toEqual([]);
    expect(intersection(null)).toEqual([]);
    expect(intersection(undefined)).toEqual([]);
  });

  //
  // stolen from https://github.com/lodash/lodash
  //

  it('should return the intersection of two arrays', () => {
    expect(intersection([2, 1], [2, 3])).toEqual([2]);
  });

  it('should return the intersection of multiple arrays', () => {
    expect(intersection([2, 1, 2, 3], [3, 4], [3, 2])).toEqual([3]);
  });

  it('should return an array of unique values', () => {
    expect(intersection([1, 1, 3, 2, 2], [5, 2, 2, 1, 4], [2, 1, 1])).toEqual([
      1, 2,
    ]);
  });

  it('should work with a single array', () => {
    expect(intersection([1, 1, 3, 2, 2])).toEqual([1, 3, 2]);
  });

  it('should match `NaN`', () => {
    expect(intersection([1, NaN, 3], [NaN, 5, NaN])).toEqual([NaN]);
  });

  it('should work with large arrays of `NaN`', () => {
    const largeArray = times(200, () => NaN);
    expect(intersection([1, NaN, 3], largeArray)).toEqual([NaN]);
  });

  it('should work with large arrays of objects', () => {
    const object = {};
    const largeArray = times(200, constant(object));

    expect(intersection([object], largeArray)).toEqual([object]);
    expect(intersection(range(200), [1])).toEqual([1]);
  });

  it('should return an array', () => {
    const array = [1, 2, 3];
    const actual = intersection(array);

    expect(actual).toEqual(jasmine.any(Array));
    expect(actual).not.toBe(array);
  });
});
Example #6
Source File: DateSelect.tsx    From UUI with MIT License 4 votes vote down vote up
DateSelect = UUIFunctionComponent({
  name: 'DateSelect',
  nodes: {
    Root: 'div',
    Calendar: 'div',
    WeekGrid: 'div',
    WeekItem: 'div',
    DayGrid: 'div',
    DayItem: 'div',
  },
  propTypes: DateSelectPropTypes,
}, (props: DateSelectFeatureProps, { nodes, NodeDataProps }) => {
  const {
    Root, Calendar,
    WeekGrid, WeekItem,
    DayGrid, DayItem,
  } = nodes

  const betweenIncludeDates = useCallback((date: Date, range: [Date, Date] | Date[]) => {
    return !isBefore(date, range[0]) && !isAfter(date, range[1])
  }, [])

  const dateInfo = useMemo(() => {
    const firstDayInMonth = startOfMonth(props.yearMonth)
    const weekdayOfFirstDayInMonth = getDay(firstDayInMonth)

    const weekdays = range(0, 7).map((i) => {
      let date = new Date(props.yearMonth)
      date = startOfWeek(date)
      date = add(date, { days: i })
      return {
        key: format(date, 'yyyy-MM-dd'),
        date: date,
        label: format(date, 'EEEEEE', { locale: zhCN }),
      };
    });

    const days = range(
      1 - weekdayOfFirstDayInMonth,
      1 - weekdayOfFirstDayInMonth + 6*7,
    ).map((i) => {
      const date = add(firstDayInMonth, { days: i - 1 })
      const selected = props.selectedDates.findIndex((i) => isSameDay(date, i)) !== -1
      const inSelectedRange = (() => {
        if (props.selectedDates.length >= 2) {
          return betweenIncludeDates(date, props.selectedDates)
        }
        return false;
      })()
      return {
        key: format(date, 'yyyy-MM-dd'),
        date: date,
        label: getDate(date),
        active: isSameMonth(props.yearMonth, date),
        selected: selected,
        inSelectedRange: inSelectedRange,
      }
    })

    return {
      weekdays,
      days
    }
  }, [props.yearMonth, props.selectedDates, betweenIncludeDates])

  return (
    <Root>
      <Calendar>
        <WeekGrid>
          {dateInfo.weekdays.map((weekday) => {
            return (
              <WeekItem key={weekday.key}>
                {weekday.label}
              </WeekItem>
            );
          })}
        </WeekGrid>
        <DayGrid
          onMouseLeave={() => {
            props.onHoverDateChange && props.onHoverDateChange(undefined)
          }}
        >
          {dateInfo.days.map((day) => {
            const hovering = props.hoverDate ? isSameDay(day.date, props.hoverDate) : false
            const inHoverRange = (() => {
              if (props.selectedDates.length === 1 && props.hoverDate) {
                return betweenIncludeDates(day.date, [props.selectedDates[0], props.hoverDate].sort((i, j) => Number(i) - Number(j)))
              }
              return false
            })()
            return (
              <DayItem
                {...NodeDataProps({
                  'active': day.active,
                  'selected': day.selected,
                  'in-selected-range': day.inSelectedRange,
                  'in-hover-range': inHoverRange,
                  'hovering': hovering,
                })}
                key={day.key}
                onClick={() => {
                  props.onSelect(day.date)
                }}
                onMouseEnter={() => {
                  props.onHoverDateChange && props.onHoverDateChange(day.date)
                }}
                onMouseLeave={() => {
                  props.onHoverDateChange && props.onHoverDateChange(undefined)
                }}
              >
                {day.label}
              </DayItem>
            )
          })}
        </DayGrid>
      </Calendar>
    </Root>
  )
})
Example #7
Source File: TimeSelect.tsx    From UUI with MIT License 4 votes vote down vote up
TimeSelect = UUIFunctionComponent({
  name: 'TimeSelect',
  nodes: {
    Root: 'div',
    SelectZone: 'div',
    Separator: 'div',
    OptionList: 'div',
    Option: 'div',
  },
  propTypes: TimeSelectPropTypes,
}, (props: TimeSelectFeatureProps, { nodes, NodeDataProps, ref }) => {
  const {
    Root, SelectZone, Separator,
    OptionList, Option,
  } = nodes

  const allOptions = useMemo(() => {
    return {
      hours: range(0, 24),
      minutes: range(0, 60),
      seconds: range(0, 60),
    }
  }, [])

  const activeOptionValue = {
    hours: props.value.getHours(),
    minutes: props.value.getMinutes(),
    seconds: props.value.getSeconds(),
  }

  const [disableHandleScroll, setDisableHandleScroll] = useState(false)
  const hourListRef = useRef<HTMLDivElement | null>(null)
  const minuteListRef = useRef<HTMLDivElement | null>(null)
  const secondListRef = useRef<HTMLDivElement | null>(null)

  const getItemHeight = useCallback((target: HTMLElement) => {
    const styles = window.getComputedStyle(target)
    const optionHeightPx = styles.getPropertyValue('--option-height')
    return Number(optionHeightPx.replace('px', ''))
  }, [])
  const scrollToValue = useCallback((value: Date, animate?: boolean) => {
    setDisableHandleScroll(true)
    const targetScrollTo = (ref: React.MutableRefObject<HTMLDivElement | null>, value: number, animate?: boolean) => {
      const target = ref.current as HTMLElement
      const itemHeight = getItemHeight(target)
      target.scrollTo({ top: value * itemHeight, behavior: animate ? "smooth" : "auto" })
    }
    targetScrollTo(hourListRef, value.getHours(), animate)
    targetScrollTo(minuteListRef, value.getMinutes(), animate)
    targetScrollTo(secondListRef, value.getSeconds(), animate)
    setTimeout(() => {
      setDisableHandleScroll(false)
    }, 500)
  }, [getItemHeight])

  useImperativeHandle(ref, () => {
    return {
      scrollToValue: scrollToValue,
    }
  })

  const scrollTo = useCallback((target: HTMLElement, top: number) => {
    target.scrollTo({ top, behavior: "smooth" })
  }, [])

  const debouncedScrollOnChange = useRef({
    hours: debounce(scrollTo, 300),
    minutes: debounce(scrollTo, 300),
    seconds: debounce(scrollTo, 300),
  })

  const handleScroll = useCallback((type: TimeSelectType) => {
    if (disableHandleScroll) return;
    const options = allOptions[type]
    return (event: React.UIEvent<HTMLDivElement, UIEvent>) => {
      const target = event.target as HTMLElement
      const itemHeight = getItemHeight(target)
      const scrollTop = target.scrollTop
      const currentIndex = Math.round((scrollTop) / itemHeight)

      const newValue = options[currentIndex];
      props.onChange(set(props.value, { [type]: newValue }))
      debouncedScrollOnChange.current[type](target, currentIndex * itemHeight)
    }
  }, [allOptions, disableHandleScroll, getItemHeight, props])

  return (
    <Root>
      {TimeSelectTypeArray.map((type, index) => {
        return (
          <React.Fragment key={type}>
            {index !== 0 && (
              <Separator>:</Separator>
            )}
            <OptionList
              ref={[hourListRef, minuteListRef, secondListRef][index]}
              key={`option-list-${type}`}
              onScroll={handleScroll(type)}
            >
              {allOptions[type].map((option) => {
                const active = activeOptionValue[type] === option
                return (
                  <Option
                    {...NodeDataProps({
                      'active': active,
                    })}
                    key={`${type}-${option}`}
                    onClick={() => {
                      const newValue = set(props.value, { [type]: option })
                      props.onChange(newValue)
                      scrollToValue(newValue)
                    }}
                  >{padStart(String(option), 2, '0')}</Option>
                )
              })}
            </OptionList>
          </React.Fragment>
        )
      })}
      <SelectZone />
    </Root>
  )
})