npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

burnout-components

v1.0.56

Published

A component library for burnout brands that contains common react-components and util functions used throughout it and it's portfolio companies

Downloads

103

Readme

Burnout Components

Table of Contents

Features

  • Styled Client/Server Components for Next.js/React (can be used with any React app)
  • Styled Client Form Components for use with Zod and TanStack Form
  • Utility functions that can run on either client or server
  • Intended for standardized styling and form validation across Burnout Brand companies for both internal and external use
  • Reduces boilerplate in Burnout Brands projects

Installing

Using npm:

npm install burnout-components

Using yarn:

yarn add burnout-components

Using bun:

bun install burnout-components

Using pnpm:

pnpm add burnout-components

Using bower:

bower install burnout-components

Once the package is installed, you can import the library using import approach:

import { MonsterButton } from 'burnout-components';

import { tryCatch } from 'burnout-components/server';

Styling

You must have Tailwind CSS installed and configured in your project. You must then import burnout-components/styles.css in either your root layout or your App file.

Client Components

These must be used with the 'use client' directive at the top of the file if you are using react 18 (I think) and above.

BurnoutButton

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • disabled: boolean (optional, default false)
  • fit: boolean (optional, default false, false = full width, true = fit to content)
  • onClick: () => void (optional)
  • red: boolean (optional, default false)
  • type: 'button' | 'submit' (optional, default submit)
import { BurnoutButton } from 'burnout-compoents';

function SomeButton() {}
  return (
    <BurnoutButton type='button' fit red onClick={() => console.log('Clicked!')}>
      Click Me!
    </BurnoutButton>
  )
}

MonsterButton

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • disabled: boolean (optional, default false)
  • fit: boolean (optional, default false, false = full width, true = fit to content)
  • onClick: () => void (optional)
  • red: boolean (optional, default false)
  • type: 'button' | 'submit' (optional, default submit)
import { MonsterButton } from 'burnout-compoents';

function SomeButton() {}
  return (
    <MonsterButton type='button' fit red onClick={() => console.log('Clicked!')}>
      Click Me!
    </MonsterButton>
  )
}

Client Form Components

These are styled components that are meant to be used with Zod and TanStack Form.

They all need to be wrapped with FormWrapper and must before the end of FormWrapper must contain a submit button like this:

<form.AppForm>
  <form.MonsterSubmitButton text='Update Role' submittingText='Updating...' />
</form.AppForm>

All available components are:

  • FormWrapper
  • BurnoutCheckbox
  • BurnoutMultiSelect
  • BurnoutRichTextEditor
  • BurnoutSelectField
  • BurnoutSubmitButton
  • BurnoutTextAreaField
  • BurnoutTextField
  • GlassCheckbox
  • GlassRichTextEditor
  • GlassSelectField
  • GlassTextAreaField
  • GlassTextField
  • MonsterCheckbox
  • MonsterMultiSelect
  • MonsterRichTextEditor
  • MonsterSelectField
  • MonsterSubmitButton
  • MonsterGlassSubmitButton
  • MonsterTextAreaField
  • MonsterTextField

MonsterGlassSubmitButton

Props and their types:

  • colorSwap: boolean (optional, default false)
  • text: string (optional, default 'Submit')
  • submittingText: string (optional, default 'Submitting...')

The MonsterGlassSubmitButton uses the TanStack Form context to determine if the form can be submitted. If there are validation errors, clicking the button will display an alert with all error messages. The button automatically disables when the form is submitting or when validation fails.

MonsterGlassSubmitButton Example

import { FormWrapper, useAppForm } from 'burnout-components';
import { z } from 'zod';

function Form() {
  const form = useAppForm({
    defaultValues: {
      name: '',
      email: ''
    },
    onSubmit: async ({ value }) => {
      // Submit form data
    },
    validators: {
      onChange: {
        name: z.string().min(1, 'Name is required'),
        email: z.string().email('Invalid email address')
      }
    }
  });

  return (
    <FormWrapper handleSubmit={form.handleSubmit}>
      <form.AppField name='name'>
        {(field) => (
          <field.GlassTextField label='Name' />
        )}
      </form.AppField>
      <form.AppField name='email'>
        {(field) => (
          <field.GlassTextField label='Email' type='email' />
        )}
      </form.AppField>
      <form.AppForm>
        <form.MonsterGlassSubmitButton 
          colorSwap
          text='Create Account' 
          submittingText='Creating...' 
        />
      </form.AppForm>
    </FormWrapper>
  );
}

Form Example

import { FormWrapper } from 'burnout-compoents';

import { useAppForm } from 'burnout-compoents/';
import { z } from 'zod';

// You can also import like this but I prefer the former

import { FormWrapper, useAppForm } from 'burnout-compoents';

function Form() {
  const form = useAppForm({
    defaultValues: {
      name: '',
      email: '',
      manager: false,
      role: 'user',
      favoriteColors: [''],
      descriptionLong: '',
      descriptionShort: ''
    },
    onSubmit: async ({ value }) => {
      const {
        name,
        email,
        manager,
        role,
        favoriteColors,
        descriptionLong,
        descriptionShort
      } = value;

      // Do something with the form values
      // This function does not have to be async
    },
    validators: {
      onChange: {
        // You would normally define this somewhere else and import it in
        // Field Errors are built in and can be checked either on change or on submit, I like on change
        name: z.string().min(1, 'Name is required'),
        email: z.string().email('Invalid email address'),
        manager: z.boolean(),
        role: z.enum(['user', 'admin'], 'Role is required'),
        favoriteColors: z
          .array(z.string())
          .min(1, 'At least one color is required'),
        descriptionLong: z.string().max(500, 'Description is too long'),
        descriptionShort: z.string().max(100, 'Description is too long')
      }
    }
  });

  const colorOptions = ['red', 'green', 'blue'];

  return (
    <FormWrapper handleSubmit={form.handleSubmit}>
      {/* Required is optional by default it is true on all relevant fields except checkboxes */}
      {/* Type is optional by default it is text on all relevant fields */}
      <form.AppField name='name'>
        {(field) => (
          <field.MonsterTextField label='Name' autoFocus type='text' />
        )}
      </form.AppField>
      <form.AppField name='email'>
        {(field) => (
          <field.MonsterTextField label='Email' required={false} type='email' />
        )}
      </form.AppField>
      <form.AppField name='manager'>
        {(field) => <field.MonsterCheckbox label='Is Manager' />}
      </form.AppField>
      <form.AppField name='role'>
        {(field) => (
          <field.MonsterSelectField label='Role'>
            <option value='user'>User</option>
            <option value='admin'>Admin</option>
          </field.MonsterSelectField>
        )}
      </form.AppField>
      <form.AppField name='favoriteColors'>
        {(field) => (
          <field.MonsterMultiSelect
            label='Favorite Colors'
            options={colorOptions}
          />
        )}
      </form.AppField>
      <form.AppField name='descriptionLong'>
        {(field) => <field.MonsterRichTextEditor label='Long Description' />}
      </form.AppField>
      <form.AppField name='descriptionShort'>
        {(field) => <field.MonsterTextAreaField label='Short Description' />}
      </form.AppField>
      <form.AppForm>
        {/* default text is 'Submit' and default submitting text is 'Submitting...' */}
        <form.MonsterSubmitButton
          text='Create Person'
          submittingText='Creating...'
        />
      </form.AppForm>
    </FormWrapper>
  );
}

Server Functions/Components

Info

Props and their types:

  • children: React.ReactNode
  • label: string

Info Example

import { Info } from 'burnout-compoents/server'

return TellingYouSomething() {
  return (
    <Info label='Something Important'>
      <p>This is some important information</p>
    </Info>
  )
}

BurnoutBreadCrumbNext

This is only for use in Next.js projects

Props and their types:

  • colorSwap: boolean(optional, default false)
  • fromLabel: string;
  • href: string
  • linkLabel: string

BurnoutBreadCrumbNext Example

import { BurnoutBreadCrumbNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <BurnoutBreadCrumbNext fromLabel='I am here' href='/somewhere' linkLabel='Somewhere' />
  )
}

BurnoutButtonLinkNext

This is only for use in Next.js projects

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • href: string
  • prefetch: boolean (optional, default true)
  • target: '_blank' | '_self' | '_parent' | '_top' (optional, default _self)

BurnoutButtonLinkNext Example

import { BurnoutButtonLinkNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <BurnoutButtonLinkNext prefetch={false} href='/somewhere' target='_blank'>
      This goes somewhere
    </BurnoutButtonLinkNext>
  )
}

BurnoutInfoCard

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • header: string

BurnoutInfoCard Example

import { BurnoutInfoCard } from 'burnout-compoents/server'

return SomeCard() {
  return (
    <BurnoutInfoCard header='Some Header'>
      <div className='w-full flex flex-col gap-3'>
        <BurnoutInfoCard colorSwap header='Some Nested Header'>
          <p>This is some nested information</p>
        </MonsterInfoCard>
      </div>
    </MonsterButtonLinkNext>
  )
}

BurnoutStyledLinkNext

This is only for use in Next.js projects

Props and their types:

  • children: React.ReactNode
  • href: string
  • prefetch: boolean (optional, default true)
  • target: '_blank' | '_self' | '_parent' | '_top' (optional, default _self)

BurnoutStyledLinkNext Example

import { BurnoutStyledLinkNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <BurnoutStyledLinkNext prefetch={false} href='/somewhere' target='_blank'>
      This goes somewhere
    </BurnoutStyledLinkNext>
  )
}

MonsterBreadCrumbNext

This is only for use in Next.js projects

Props and their types:

  • colorSwap: boolean (optional, default false);
  • fromLabel: string;
  • href: string
  • linkLabel: string

MonsterBreadCrumbNext Example

import { MonsterBreadCrumbNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <MonsterBreadCrumbNext fromLabel='I am here' href='/somewhere' linkLabel='Somewhere' />
  )
}

MonsterButtonLinkNext

This is only for use in Next.js projects

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • href: string
  • prefetch: boolean (optional, default true)
  • target: '_blank' | '_self' | '_parent' | '_top' (optional, default _self)

MonsterButtonLinkNext Example

import { MonsterButtonLinkNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <MonsterButtonLinkNext prefetch={false} href='/somewhere' target='_blank'>
      This goes somewhere
    </MonsterButtonLinkNext>
  )
}

MonsterGlassButtonLinkNext

This is only for use in Next.js projects

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • href: string
  • prefetch: boolean (optional, default true)
  • target: '_blank' | '_self' | '_parent' | '_top' (optional, default _self)

MonsterGlassButtonLinkNext Example

import { MonsterGlassButtonLinkNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <MonsterGlassButtonLinkNext prefetch={false} href='/somewhere' target='_blank'>
      This goes somewhere
    </MonsterGlassButtonLinkNext>
  )
}

MonsterInfoCard

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • header: string

MonsterInfoCard Example

import { MonsterInfoCard } from 'burnout-compoents/server'

return SomeCard() {
  return (
    <MonsterInfoCard header='Some Header'>
      <div className='w-full flex flex-col gap-3'>
        <MonsterInfoCard colorSwap header='Some Nested Header'>
          <p>This is some nested information</p>
        </MonsterInfoCard>
      </div>
    </MonsterButtonLinkNext>
  )
}

MonsterStyledLinkNext

This is only for use in Next.js projects

Props and their types:

  • children: React.ReactNode
  • href: string
  • prefetch: boolean (optional, default true)
  • target: '_blank' | '_self' | '_parent' | '_top' (optional, default _self)

MonsterStyledLinkNext Example

import { MonsterStyledLinkNext } from 'burnout-compoents/server'

return LinkingYouToSomething() {
  return (
    <MonsterStyledLinkNext prefetch={false} href='/somewhere' target='_blank'>
      This goes somewhere
    </MonsterStyledLinkNext>
  )
}

GlassMonsterBreadCrumbNext

This is only for use in Next.js projects

Props and their types:

  • colorSwap: boolean (optional, default false)
  • fromLabel: string
  • href: string
  • linkLabel: string

The GlassMonsterBreadCrumbNext component provides a glass-style breadcrumb navigation element using the MonsterGlassButtonLinkNext component internally. It displays a link button followed by a chevron icon and the current page label.

GlassMonsterBreadCrumbNext Example

import { GlassMonsterBreadCrumbNext } from 'burnout-compoents/server'

return BreadcrumbNavigation() {
  return (
    <GlassMonsterBreadCrumbNext 
      colorSwap 
      fromLabel="Current Page" 
      href="/previous-page" 
      linkLabel="Previous Page" 
    />
  )
}

GlassMonsterInfoCard

Props and their types:

  • children: React.ReactNode
  • colorSwap: boolean (optional, default false)
  • header: number | string

The GlassMonsterInfoCard component provides a glass-style card with a header and content area. It features a backdrop blur effect and subtle transparency for a modern UI appearance.

GlassMonsterInfoCard Example

import { GlassMonsterInfoCard } from 'burnout-compoents/server'

return InformationDisplay() {
  return (
    <GlassMonsterInfoCard header="Important Information">
      <div className="space-y-4">
        <p>This is some important information displayed in a glass-style card.</p>
        <GlassMonsterInfoCard colorSwap header="Additional Details">
          <p>You can nest these cards for hierarchical information display.</p>
        </GlassMonsterInfoCard>
      </div>
    </GlassMonsterInfoCard>
  )
}

TailwindLoadingSpinner

This is small and meant for inline loading spinners. It is not a full page loading.

Props and their types:

  • fill: 'blue' | 'green' | 'red' | 'yellow' (optional, default blue)

TailwindLoadingSpinner Example

import { TailwindLoadingSpinner } from 'burnout-compoents/server'

return SomeBadLoading() {
  return (
    <TailwindLoadingSpinner fill='red' />
  )
}

Utility Functions

capitalizeFirstLetters

capitalizeFirstLetters Example

import { capitalizeFirstLetters } from 'burnout-components/server';

const text = 'hello world';

const newText = capitalizeFirstLetters(text);

console.log(newText); // Output: Hello World

createDollarAmount

createDollarAmount Example

import { createDollarAmount } from 'burnout-components/server';

const amountString = '200';

const newAmountOne = createDollarAmount(amountString);

console.log(newAmountOne); // Output: $200.00

const amountNumber = 200;

const newAmountTwo = createDollarAmount(amountNumber);

console.log(newAmountTwo); // Output: $200.00

createQueryStringNext

This is only for use in Next.js projects.

createQueryStringNext Example

import { createQueryStringNext } from 'burnout-components/server';
import { usePathname, useRouter, useSearchParams } from 'next/naviagtion';

const pathname = usePathname();
const router = useRouter();
const searchParams = useSearchParams();

function handleSubmit(search: string) {
  router.push(`${pathname}?${createQueryString('search', search, searchParams}`)
}

extractNumber

extractNumber Example

import { extractNumber } from 'burnout-components/server';

const inputString = '2,812.30 refund minus 25% CANCELLATION FEE.';

const result = extractNumber(inputString);

console.log(result); // Output: 2812.3

formatPhone

formatPhone Example

import { formatPhone } from 'burnout-components/server';

const phoneNumber = '1234567890';

const formattedPhone = formatPhone(phoneNumber);

console.log(formattedPhone); // Output: (123) 456-7890

trimStringProperties

trimStringProperties Example

import { trimStringProperties } from 'burnout-components/server';

const userInput = {
  name: '  John Doe  ',
  email: ' [email protected] ',
  age: 30,
  isActive: true,
  description: '  This is a description with extra spaces  '
};

const trimmedData = trimStringProperties(userInput);

console.log(trimmedData);
// Output: {
//   name: 'John Doe',
//   email: '[email protected]',
//   age: 30,
//   isActive: true,
//   description: 'This is a description with extra spaces'
// }

truncateText

truncateText Example

import { truncateText } from 'burnout-components/server';

const text 'Imagine this is super long text that needs to be truncated';

const truncatedText = truncateText(text, 20);

console.log(truncatedText); // Output: Imagine this is super long...

tryCatch

tryCatch Example

import { tryCatch } from 'burnout-components/server';

async function something() {
  const { data, error } = await tryCatch(async () => {
    const response = await fetch('/api/some-endpoint');
    return response.json();
  });

  if (error) {
    console.error('Error fetching data:', error);
  } else {
    console.log('Fetched data:', data);
  }
}