Search
⌘K

Random

Random utilities like getRandomString, etc.

Example Usage

import { 
  getRandomString,
  getRandomString2, 
  getRandomInteger, 
  getRandomArrayItem, 
  getRandomColor, 
  getRandomImage,
  getRandomDateInRange,
} from './random';

// getRandomString
getRandomString(); // 1642345678-12345

// getRandomString2
getRandomString2() // 12345

// getRandomInteger(min, max)
getRandomInteger(1, 10); // 1
getRandomInteger(1, 10); // 2
getRandomInteger(1, 10); // 10

// getRandomArrayItem(any[])
getRandomArrayItem([1, 2, 3]); // 2
getRandomArrayItem([1, 2, 3]); // 3

// getRandomColor
getRandomColor(); // total random { h: 120, s: 100, l: 50, hsl: 'hsl(120 100% 50% )' }
getRandomColor({h: 50}); // fixed h { h: 50, s: 100, l: 50, hsl: 'hsl(50 100% 50% )' }
getRandomColor({h: 50, s: 50}); // fixed h and s { h: 50, s: 50, l: 50, hsl: 'hsl(50 50% 50% )' }
getRandomColor({h: 50, l: 50}); // fixed h and l { h: 50, s: 50, l: 50, hsl: 'hsl(50 50% 50% )' }

// getRandomImage
getRandomImage(); // https://picsum.photos/900/700?random=1
getRandomImage({ w: 600, h: 400 }); // https://picsum.photos/600/400?random=2

// getRandomDateInRange
getRandomDateInRange(new Date('2022-01-01'), new Date('2022-12-31')); // Date 2022-08-01

Dependencies

registryhttps://shadcn-registry-ts.vercel.app/r/util-math.json

Auto Install

npx shadcn@latest add https://shadcn-registry-ts.vercel.app/r/util-random.json

Manual Install

random.ts
/**
 * Source: http://localhost:3000
 */

import { lerp, clamp } from './math';

/** Get a random string in format `1642345678-12345`. Always 19 characters. */
export const getRandomString = () => `${new Date().valueOf()}-${Math.random().toString(36).substring(3, 8)}`;

/** Get a random string in format `12345`. Always 5 characters. */
export const getRandomString2 = () => Math.random().toString(36).substring(3, 8);


/**
 * Get a random integer between min and max. Min andmax are included.  
 * Result is also clamped.
 */
export const getRandomInteger = (
  /** Minumum value passibile. */
  min: number,
  /** Maximum value possible. */
  max: number
) => {
  const value = lerp({ min, max, t: Math.random() });
  return clamp({ min, max, value: Math.round(value) });
};

/**
 * Get a random item from an array
 */
export const getRandomArrayItem = <T>(
  /** Array from which you want to get a random item. */
  array: T[]
): T => {
  const index = getRandomInteger(0, array.length - 1);
  return array[index];
};

/**
 * Get a random color in HSL format.  
 * If you provide:
 * - nothing, it will generate a random color.
 * - `{ h: 20 }`, it will generate a random color with always 20 as hue.
 * - `{ s: 60 }`, it will generate a random color with always 60 as saturation.
 * - `{ l: 80 }`, it will generate a random color with always 80 as lightness.
 * - `{ h: 10, s: 20 }` or `{ h: 10, l: 20 }` or `{ s: 10, l: 20 }`, it will generate a random color with the fixed part you provided. What you don't provide will be random.
 */
export const getRandomColor = ({
  h,
  s,
  l,
}: {
  /** Hue. 0-360*/
  h?: number,
  /** Saturation. 0-100. */
  s?: number,
  /** Lightness. 0-100. */
  l?: number,
} = {}) => {
  const _h = h ?? getRandomInteger(0, 360);
  const _s = s ?? getRandomInteger(0, 100);
  const _l = l ?? getRandomInteger(0, 100);
  return {
    h: _h,
    s: _s,
    l: _l,
    hsl: `hsl(${_h} ${_s}% ${_l}%)`,
  };
};

/**
 * Get a random image (for placeholder).
 * Internally it builds an URL for Picsum.  
 * i.e. `https://picsum.photos/200/300?random=234`
 */
export const getRandomImage = ({
  w = 900,
  h = 700,
}: {
  /** Width. Default to 900. */
  w?: number,
  /** Height. Default to 700. */
  h?: number,
} = {}) => {

  // https://picsum.photos/200/300?random=234
  const url = new URL(`https://picsum.photos/${w}/${h}`);
  url.searchParams.append('random', getRandomInteger(0, 1000).toString());

  return url.toString();
};

/**
 * Get a random `Date` between start and end `Date`.  
 * Start and end could be included.
 */
export const getRandomDateInRange = (start: Date, end: Date) => {
  const DAY_IN_MS = 1000 * 60 * 60 * 24;
  const differenceBetweenStartAndEnd_inMs = end.getTime() - start.getTime();
  const differenceBetweenStartAndEnd_inDays = differenceBetweenStartAndEnd_inMs / DAY_IN_MS;
  const randomNumberOfDays = getRandomInteger(0, differenceBetweenStartAndEnd_inDays);
  const randomNumberOfDays_inMs = randomNumberOfDays * DAY_IN_MS;
  const randomDate = new Date(start.getTime() + randomNumberOfDays_inMs);
  return randomDate;
};

Test

random.test.ts
import { describe, it, expect } from 'vitest';
import { repeatSyncFn } from '../utility-framework/vitest.utils';

import {
  getRandomString,
  getRandomString2,
  getRandomInteger,
  getRandomArrayItem,
  getRandomColor,
  getRandomImage,
  getRandomDateInRange,
} from './random';

describe('random - getRandomString', () => {

  it('do it', async () => {
    repeatSyncFn(10_000, () => {
      const value = getRandomString();
      expect(value).toBeTypeOf('string');
      expect(value.length).toBe(19);
    });
  });
});

describe('random - getRandomString2', () => {

  it('do it', async () => {
    repeatSyncFn(10_000, () => {
      const value = getRandomString2();
      expect(value).toBeTypeOf('string');
      expect(value.length).toBe(5);
    });
  });
});

describe('random - getRandomInteger', () => {

  it('do it', async () => {
    repeatSyncFn(10_000, () => {
      const value = getRandomInteger(0, 100);
      expect(value).toBeGreaterThanOrEqual(0);
      expect(value).toBeLessThanOrEqual(100);
    });
  });

});


describe('random - getRandomArrayItem', () => {

  it('do it', async () => {
    repeatSyncFn(10_000, () => {
      const value = getRandomArrayItem([1, 2, 3]);
      expect(value).oneOf([1, 2, 3]);
    });
  });

});


describe('random - getRandomColor', () => {

  it('do it', async () => {
    // total random
    repeatSyncFn(1_000, () => {
      const value = getRandomColor();
      expect(value.h).toBeGreaterThanOrEqual(0);
      expect(value.h).toBeLessThanOrEqual(360);
      expect(value.s).toBeGreaterThanOrEqual(0);
      expect(value.s).toBeLessThanOrEqual(100);
      expect(value.l).toBeGreaterThanOrEqual(0);
      expect(value.l).toBeLessThanOrEqual(100);
    });

    // fixed h
    repeatSyncFn(1_000, () => {
      const value = getRandomColor({ h: 100 });
      expect(value.h).toBe(100);
      expect(value.s).toBeGreaterThanOrEqual(0);
      expect(value.s).toBeLessThanOrEqual(100);
      expect(value.l).toBeGreaterThanOrEqual(0);
      expect(value.l).toBeLessThanOrEqual(100);
    });

    // fixed s
    repeatSyncFn(1_000, () => {
      const value = getRandomColor({ s: 100 });
      expect(value.h).toBeGreaterThanOrEqual(0);
      expect(value.h).toBeLessThanOrEqual(360);
      expect(value.s).toBe(100);
      expect(value.l).toBeGreaterThanOrEqual(0);
      expect(value.l).toBeLessThanOrEqual(100);
    });

    // fixed l
    repeatSyncFn(1_000, () => {
      const value = getRandomColor({ l: 100 });
      expect(value.h).toBeGreaterThanOrEqual(0);
      expect(value.h).toBeLessThanOrEqual(360);
      expect(value.s).toBeGreaterThanOrEqual(0);
      expect(value.s).toBeLessThanOrEqual(100);
      expect(value.l).toBe(100);
    });

    // fixed h, s
    repeatSyncFn(1_000, () => {
      const value = getRandomColor({ h: 100, s: 100 });
      expect(value.h).toBe(100);
      expect(value.s).toBe(100);
      expect(value.l).toBeGreaterThanOrEqual(0);
      expect(value.l).toBeLessThanOrEqual(100);
    });

    // fixed h, l
    repeatSyncFn(1_000, () => {
      const value = getRandomColor({ h: 100, l: 100 });
      expect(value.h).toBe(100);
      expect(value.s).toBeGreaterThanOrEqual(0);
      expect(value.s).toBeLessThanOrEqual(100);
      expect(value.l).toBe(100);
    });

    // fixed s, l
    repeatSyncFn(1_000, () => {
      const value = getRandomColor({ s: 100, l: 100 });
      expect(value.h).toBeGreaterThanOrEqual(0);
      expect(value.h).toBeLessThanOrEqual(360);
      expect(value.s).toBe(100);
      expect(value.l).toBe(100);
    });
  });

});


describe('random - getRandomImage', () => {

  it('do it', async () => {
    repeatSyncFn(10_000, () => {
      const value = getRandomImage();
      expect(value).toBeTypeOf('string');
      expect(value.startsWith('https://picsum.photos/')).toBe(true);
    });
  });

});

describe('random - getRandomDateInRange', () => {

  it('do it', async () => {
    repeatSyncFn(10_000, () => {
      const start = new Date('2022-01-01');
      const end = new Date('2022-12-31');
      const value = getRandomDateInRange(start, end);
      expect(value).toBeInstanceOf(Date);
      expect(value.getTime()).toBeGreaterThanOrEqual(start.getTime());
      expect(value.getTime()).toBeLessThanOrEqual(end.getTime());
    });
  });

});

Command Palette

Search for a command to run...