CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-tremor--react

Tremor React is a comprehensive React component library built on Tailwind CSS providing 60+ components for building data visualizations, charts, and analytical dashboards.

Overview
Eval results
Files

input-elements.mddocs/

Input Components

Form controls and interactive elements.

⚠️ All inputs share common input props: error, errorMessage, disabled, placeholder, icon.

Input Selection

ComponentUse CaseKey Props
ButtonActions, submissionsvariant, loading, icon, iconPosition
TextInputSingle-line textStandard input props + type
NumberInputNumeric valuesenableStepper, step, min, max, onSubmit
TextareaMulti-line textautoHeight, rows
SwitchBoolean togglechecked, onChange, color
SelectSingle selection dropdownenableClear + requires <SelectItem> children
MultiSelectMultiple selectionsplaceholderSearch + requires <MultiSelectItem>
SearchSelectSearchable single selectsearchValue, onSearchValueChange + <SearchSelectItem>
DatePickerDate selectionminDate, maxDate, locale, weekStartsOn
DateRangePickerDate rangeenableSelect + optional <DateRangePickerItem> presets
TabsContent switchingUse TabGroup/TabList/Tab/TabPanels/TabPanel

Controlled vs Uncontrolled

All inputs support both modes (controlled recommended):

// Controlled (recommended)
const [value, setValue] = useState('');
<TextInput value={value} onValueChange={setValue} />

// Uncontrolled
<TextInput defaultValue="initial" />

Button

interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
  icon?: React.ElementType;
  iconPosition?: "left" | "right";
  size?: Size;
  color?: Color;
  variant?: "primary" | "secondary" | "light";
  disabled?: boolean;
  loading?: boolean;
  loadingText?: string;
  tooltip?: string;
}

Examples:

import { Button } from '@tremor/react';
import { PlusIcon, DownloadIcon } from '@heroicons/react/24/outline';

<Button>Click me</Button>
<Button icon={PlusIcon} variant="primary" color="blue">Add Item</Button>
<Button loading loadingText="Saving...">Save</Button>
<Button icon={DownloadIcon} iconPosition="right" variant="secondary">Export</Button>

TextInput

interface TextInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange'> {
  defaultValue?: string;
  value?: string;
  onValueChange?: (value: string) => void;
  icon?: React.ElementType | React.JSXElementConstructor<any>;
  error?: boolean;
  errorMessage?: string;
  disabled?: boolean;
  // Plus all standard HTML input props: type, placeholder, pattern, etc.
}

Examples:

import { TextInput } from '@tremor/react';
import { MagnifyingGlassIcon, EnvelopeIcon } from '@heroicons/react/24/outline';

// With icon
<TextInput icon={MagnifyingGlassIcon} placeholder="Search..." />

// With validation
function EmailInput() {
  const [email, setEmail] = useState('');
  const [error, setError] = useState('');

  return (
    <TextInput
      icon={EnvelopeIcon}
      type="email"
      value={email}
      onValueChange={(v) => {
        setEmail(v);
        setError(v && !v.includes('@') ? 'Invalid email' : '');
      }}
      error={!!error}
      errorMessage={error}
    />
  );
}

NumberInput

interface NumberInputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value'> {
  value?: number;
  defaultValue?: number;
  onValueChange?: (value: number) => void;
  step?: string | number;
  enableStepper?: boolean; // Show +/- buttons
  onSubmit?: (value: number) => void;
  min?: number;
  max?: number;
  icon?: React.ElementType;
  error?: boolean;
  errorMessage?: string;
  disabled?: boolean;
}

Examples:

import { NumberInput } from '@tremor/react';

<NumberInput placeholder="Enter amount" min={0} max={1000} />
<NumberInput defaultValue={10} step={5} enableStepper={true} />

// Controlled with decimals
const [price, setPrice] = useState(19.99);
<NumberInput value={price} onValueChange={setPrice} step={0.01} enableStepper={true} />

Textarea

interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextAreaElement> {
  defaultValue?: string | number;
  value?: string | number;
  error?: boolean;
  errorMessage?: string;
  disabled?: boolean;
  autoHeight?: boolean; // Automatically adjust height to content
  onValueChange?: (value: any) => void;
}

Examples:

import { Textarea } from '@tremor/react';

<Textarea placeholder="Enter your message..." rows={4} />
<Textarea autoHeight={true} placeholder="Auto-expanding textarea" />

// With validation
const [comment, setComment] = useState('');
const isValid = comment.length <= 500;
<Textarea
  value={comment}
  onValueChange={setComment}
  error={!isValid}
  errorMessage={!isValid ? 'Max 500 characters' : undefined}
/>

Switch

interface SwitchProps extends Omit<React.HTMLAttributes<HTMLDivElement>, 'onChange'> {
  checked?: boolean;
  defaultChecked?: boolean;
  onChange?: (value: boolean) => void;
  color?: Color;
  name?: string;
  error?: boolean;
  errorMessage?: string;
  disabled?: boolean;
  required?: boolean;
  id?: string;
  tooltip?: string;
}

Examples:

import { Switch } from '@tremor/react';

<Switch defaultChecked={true} />

// Controlled
const [enabled, setEnabled] = useState(false);
<div className="flex items-center gap-3">
  <Switch checked={enabled} onChange={setEnabled} color="blue" id="notifications" />
  <label htmlFor="notifications">Enable notifications</label>
</div>

Select

Requires <SelectItem> children. Use for single selection from a list.

interface SelectProps {
  value?: string;
  name?: string;
  defaultValue?: string;
  onValueChange?: (value: string) => void;
  placeholder?: string;
  disabled?: boolean;
  icon?: React.JSXElementConstructor<any>;
  enableClear?: boolean;
  required?: boolean;
  error?: boolean;
  errorMessage?: string;
  children: React.ReactNode; // SelectItem components
}

interface SelectItemProps {
  value: string;
  icon?: React.ElementType;
  children: React.ReactNode;
}

Examples:

import { Select, SelectItem } from '@tremor/react';

// Basic
<Select placeholder="Select country...">
  <SelectItem value="us">United States</SelectItem>
  <SelectItem value="uk">United Kingdom</SelectItem>
  <SelectItem value="ca">Canada</SelectItem>
</Select>

// Controlled with clear
const [country, setCountry] = useState('');
<Select value={country} onValueChange={setCountry} enableClear={true}>
  <SelectItem value="us">United States</SelectItem>
  <SelectItem value="uk">United Kingdom</SelectItem>
</Select>

// With validation
<Select error={true} errorMessage="Please select a country" required={true}>
  <SelectItem value="us">United States</SelectItem>
</Select>

MultiSelect

Requires <MultiSelectItem> children. Built-in search functionality.

interface MultiSelectProps {
  defaultValue?: string[];
  name?: string;
  value?: string[];
  onValueChange?: (value: string[]) => void;
  placeholder?: string;
  placeholderSearch?: string;
  disabled?: boolean;
  icon?: React.ElementType;
  required?: boolean;
  error?: boolean;
  errorMessage?: string;
  children: React.ReactNode; // MultiSelectItem components
}

interface MultiSelectItemProps {
  value: string;
  children: React.ReactNode;
}

Examples:

import { MultiSelect, MultiSelectItem } from '@tremor/react';

<MultiSelect placeholder="Select categories...">
  <MultiSelectItem value="electronics">Electronics</MultiSelectItem>
  <MultiSelectItem value="clothing">Clothing</MultiSelectItem>
</MultiSelect>

// Controlled
const [selected, setSelected] = useState<string[]>([]);
<MultiSelect
  value={selected}
  onValueChange={setSelected}
  placeholderSearch="Search categories..."
>
  <MultiSelectItem value="electronics">Electronics</MultiSelectItem>
  <MultiSelectItem value="clothing">Clothing</MultiSelectItem>
</MultiSelect>

SearchSelect

Requires <SearchSelectItem> children. Searchable single-select with filtering.

interface SearchSelectProps {
  defaultValue?: string;
  name?: string;
  searchValue?: string;
  onSearchValueChange?: (value: string) => void;
  value?: string;
  onValueChange?: (value: string) => void;
  placeholder?: string;
  disabled?: boolean;
  icon?: React.ElementType;
  required?: boolean;
  error?: boolean;
  errorMessage?: string;
  enableClear?: boolean;
  children: React.ReactNode; // SearchSelectItem components
}

interface SearchSelectItemProps {
  value: string;
  icon?: React.ElementType;
  children: React.ReactNode;
}

Examples:

import { SearchSelect, SearchSelectItem } from '@tremor/react';

<SearchSelect placeholder="Search for a country..." enableClear={true}>
  <SearchSelectItem value="us">United States</SearchSelectItem>
  <SearchSelectItem value="uk">United Kingdom</SearchSelectItem>
  <SearchSelectItem value="ca">Canada</SearchSelectItem>
  {/* More items... */}
</SearchSelect>

DatePicker

Date picker with calendar popup, localization, and constraints.

interface DatePickerProps {
  value?: Date;
  defaultValue?: Date;
  onValueChange?: (value: Date | undefined) => void;
  minDate?: Date;
  maxDate?: Date;
  placeholder?: string;
  disabled?: boolean;
  color?: Color;
  locale?: Locale; // from date-fns
  enableClear?: boolean;
  displayFormat?: string;
  enableYearNavigation?: boolean;
  weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6; // 0 = Sunday
  disabledDates?: Date[];
}

Examples:

import { DatePicker } from '@tremor/react';
import { de } from 'date-fns/locale';

<DatePicker placeholder="Select a date" />

// With constraints
const [date, setDate] = useState<Date>();
<DatePicker
  value={date}
  onValueChange={setDate}
  maxDate={new Date()}
  minDate={new Date(1900, 0, 1)}
  enableClear={true}
/>

// Localized
<DatePicker
  locale={de}
  weekStartsOn={1}
  displayFormat="dd.MM.yyyy"
  enableYearNavigation={true}
/>

DateRangePicker

Date range picker with optional presets.

interface DateRangePickerProps {
  value?: { from?: Date; to?: Date; selectValue?: string };
  defaultValue?: { from?: Date; to?: Date; selectValue?: string };
  onValueChange?: (value: { from?: Date; to?: Date; selectValue?: string }) => void;
  enableSelect?: boolean; // Show preset dropdown (default: true)
  minDate?: Date;
  maxDate?: Date;
  placeholder?: string;
  selectPlaceholder?: string;
  disabled?: boolean;
  color?: Color;
  locale?: Locale;
  enableClear?: boolean;
  displayFormat?: string;
  enableYearNavigation?: boolean;
  weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
  disabledDates?: Date[];
  children?: React.ReactElement[] | React.ReactElement; // DateRangePickerItem presets
}

interface DateRangePickerItemProps {
  value: string;
  from: Date;
  to?: Date;
  children: React.ReactNode;
}

Examples:

import { DateRangePicker, DateRangePickerItem } from '@tremor/react';
import { subDays } from 'date-fns';

// With default presets
<DateRangePicker placeholder="Select date range" />

// Custom presets
const today = new Date();
<DateRangePicker>
  <DateRangePickerItem value="last7" from={subDays(today, 7)} to={today}>
    Last 7 days
  </DateRangePickerItem>
  <DateRangePickerItem value="last30" from={subDays(today, 30)} to={today}>
    Last 30 days
  </DateRangePickerItem>
</DateRangePicker>

// Calendar only (no presets)
<DateRangePicker enableSelect={false} />

Tabs

Tab navigation system for content switching.

interface TabGroupProps {
  defaultIndex?: number;
  index?: number;
  onIndexChange?: (index: number) => void;
  children: React.ReactNode; // TabList and TabPanels
}

interface TabListProps {
  color?: Color;
  variant?: "line" | "solid";
  children: React.ReactElement[] | React.ReactElement; // Tab components
}

interface TabProps {
  icon?: React.ElementType;
  children: React.ReactNode;
}

interface TabPanelsProps {
  children: React.ReactNode; // TabPanel components
}

interface TabPanelProps {
  children: React.ReactNode;
}

Examples:

import { TabGroup, TabList, Tab, TabPanels, TabPanel } from '@tremor/react';
import { ChartBarIcon, TableCellsIcon } from '@heroicons/react/24/outline';

// Basic
<TabGroup>
  <TabList>
    <Tab>Overview</Tab>
    <Tab>Details</Tab>
  </TabList>
  <TabPanels>
    <TabPanel><div>Overview content</div></TabPanel>
    <TabPanel><div>Details content</div></TabPanel>
  </TabPanels>
</TabGroup>

// With icons
<TabGroup>
  <TabList>
    <Tab icon={ChartBarIcon}>Chart View</Tab>
    <Tab icon={TableCellsIcon}>Table View</Tab>
  </TabList>
  <TabPanels>
    <TabPanel>{/* Chart */}</TabPanel>
    <TabPanel>{/* Table */}</TabPanel>
  </TabPanels>
</TabGroup>

// Controlled
const [activeTab, setActiveTab] = useState(0);
<TabGroup index={activeTab} onIndexChange={setActiveTab}>
  {/* ... */}
</TabGroup>

Form Validation Pattern

import { Card, TextInput, Select, SelectItem, Button } from '@tremor/react';

function Form() {
  const [name, setName] = useState('');
  const [country, setCountry] = useState('');
  const [errors, setErrors] = useState({ name: '', country: '' });

  const validate = () => {
    const newErrors = { name: '', country: '' };
    if (!name) newErrors.name = 'Name is required';
    if (!country) newErrors.country = 'Select a country';
    setErrors(newErrors);
    return !Object.values(newErrors).some(e => e);
  };

  return (
    <Card className="space-y-4">
      <TextInput
        value={name}
        onValueChange={setName}
        error={!!errors.name}
        errorMessage={errors.name}
      />
      <Select
        value={country}
        onValueChange={setCountry}
        error={!!errors.country}
        errorMessage={errors.country}
      >
        <SelectItem value="us">United States</SelectItem>
      </Select>
      <Button onClick={() => validate() && console.log('Submit')}>Submit</Button>
    </Card>
  );
}

Common Mistakes

  • ❌ Forgetting SelectItem children for Select (required!)
  • ❌ Using onChange instead of onValueChange for controlled inputs
  • ❌ Type mismatch: onValueChange takes string for TextInput, number for NumberInput
  • ❌ Forgetting enableClear when clearing is needed
  • ❌ Wrong Tabs structure (must use TabGroup > TabList + TabPanels)

See Also

Install with Tessl CLI

npx tessl i tessl/npm-tremor--react

docs

chart-elements.md

common-props.md

icon-elements.md

index.md

input-elements.md

layout-elements.md

list-elements.md

text-elements.md

types.md

visualization-elements.md

tile.json