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
- Installing
- Styling
- Client Components
- Client Form Components
- Server Functions/Components
- Utility Functions
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-componentsUsing yarn:
yarn add burnout-componentsUsing bun:
bun install burnout-componentsUsing pnpm:
pnpm add burnout-componentsUsing bower:
bower install burnout-componentsOnce 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 WorldcreateDollarAmount
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.00createQueryStringNext
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.3formatPhone
formatPhone Example
import { formatPhone } from 'burnout-components/server';
const phoneNumber = '1234567890';
const formattedPhone = formatPhone(phoneNumber);
console.log(formattedPhone); // Output: (123) 456-7890trimStringProperties
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);
}
}