Mantine Led

Undolog

@gfazioli/mantine-led

A highly customizable LED indicator component for React applications built with Mantine. Provides visual feedback for status indicators with support for colors, sizes, animations, and controlled states.

Installation

yarn add @gfazioli/mantine-led

After installation import package styles at the root of your application:

import '@gfazioli/mantine-led/styles.css';

You can import styles within a layer @layer mantine-led by importing @gfazioli/mantine-led/styles.layer.css file.

import '@gfazioli/mantine-led/styles.layer.css';

Usage

Explore all available props and see the component in action:

Variant
Color
Size
Radius
Intensity
Animation duration
Label position
import { Led } from '@gfazioli/mantine-led';

function Demo() {
  return (
    <Led/>
  );
}

Controlled

The Led component is fully controlled through the value prop. Here's an example of controlling the LED state:

import { useState } from 'react';
import { Button, Group, Stack } from '@mantine/core';
import { Led } from '@gfazioli/mantine-led';

function Demo() {
  const [value, { open, close, toggle }] = useDisclosure(false);

  return (
    <Stack align="center">
      <Led value={value} size="xl" />
      <Group>
        <Button onClick={open} variant="light" color="green">
          Turn On
        </Button>
        <Button onClick={close} variant="light" color="red">
          Turn Off
        </Button>
        <Button onClick={toggle} variant="light">
          Toggle
        </Button>
      </Group>
    </Stack>
  );
}

Colors

The Led component supports all Mantine theme colors. Use the color prop to set the LED color:

import { Group } from '@mantine/core';
import { Led } from '@gfazioli/mantine-led';

function Demo() {
  return (
    <Group>
      <Led color="red" />
      <Led color="green" />
      <Led color="blue" />
      <Led color="yellow" />
      <Led color="orange" />
      <Led color="cyan" />
      <Led color="pink" />
      <Led color="violet" />
    </Group>
  );
}

Animations

Add visual feedback with built-in animations. The component supports multiple animation types:

  • pulse: Smooth pulsing effect (default)
  • flash: Quick flashing
  • breathe: Slow breathing effect
  • blink: Regular blinking
  • glow: Glowing effect with increased intensity

Pulse

Flash

Breathe

Blink

Glow

import { Group, Stack, Text } from '@mantine/core';
import { Led } from '@gfazioli/mantine-led';

function Demo() {
  return (
    <Group>
      <Stack align="center" gap="xs">
        <Led animate animationType="pulse" size="lg" />
        <Text size="xs">Pulse</Text>
      </Stack>
      <Stack align="center" gap="xs">
        <Led animate animationType="flash" size="lg" color="red" />
        <Text size="xs">Flash</Text>
      </Stack>
      <Stack align="center" gap="xs">
        <Led animate animationType="breathe" size="lg" color="blue" />
        <Text size="xs">Breathe</Text>
      </Stack>
      <Stack align="center" gap="xs">
        <Led animate animationType="blink" size="lg" color="yellow" />
        <Text size="xs">Blink</Text>
      </Stack>
      <Stack align="center" gap="xs">
        <Led animate animationType="glow" size="lg" color="cyan" />
        <Text size="xs">Glow</Text>
      </Stack>
    </Group>
  );
}

Labels

Add descriptive labels to your LED indicators with full customization support:

Power
Standby
Online
Active
Custom Label
import { Badge, Group, Stack } from '@mantine/core';
import { Led } from '@gfazioli/mantine-led';

function Demo() {
  return (
    <Stack gap="lg">
      <Group>
        <Led label="Power" />
        <Led value={false} label="Standby" color="gray" />
      </Group>

      <Group>
        <Led label="Online" labelPosition="left" color="green" />
        <Led label="Active" labelPosition="right" color="blue" />
      </Group>

      <Group>
        <Led
          label={<Badge size="sm" variant="light">Custom Label</Badge>}
          color="violet"
        />
      </Group>
    </Stack>
  );
}

The label prop accepts any React node, allowing you to use custom components like badges, icons, or formatted text. Use labelPosition to control whether the label appears on the left or right side of the LED.

Styles API

Led supports Styles API, you can add styles to any inner element of the component with classNames prop. Follow Styles API documentation to learn more.

You can customize the appearance of the Led component using the Styles API. This allows you to modify styles for various parts of the component, such as the root, led, and label.

Example Label

Component Styles API

Hover over selectors to highlight corresponding elements

/*
 * Hover over selectors to apply outline styles
 *
 */

Use Cases

System Status Panel

Monitor multiple system components with organized LED indicators:

System Status Panel

Network

Internet
LAN
VPN

Services

Database
API Server
Cache

Resources

CPU Load
Memory
Disk Space

Security

Firewall
SSL Cert
Auth Service
import { Group, Paper, SimpleGrid, Stack, Text, Title } from '@mantine/core';
import { Led } from '@gfazioli/mantine-led';

function Demo() {
  return (
    <Paper p="xl" withBorder>
      <Stack gap="lg">
        <Title order={3}>System Status Panel</Title>
        
        <SimpleGrid cols={2}>
          <Stack gap="md">
            <Text fw={500} size="sm">Network</Text>
            <Stack gap="xs">
              <Led value label="Internet" color="green" labelPosition="left" />
              <Led value label="LAN" color="green" labelPosition="left" />
              <Led value={false} label="VPN" color="gray" labelPosition="left" />
            </Stack>
          </Stack>

          <Stack gap="md">
            <Text fw={500} size="sm">Services</Text>
            <Stack gap="xs">
              <Led
                value
                label="Database"
                color="green"
                labelPosition="left"
                animate
                animationType="pulse"
              />
              <Led value label="API Server" color="green" labelPosition="left" />
              <Led value label="Cache" color="yellow" labelPosition="left" />
            </Stack>
          </Stack>

          <Stack gap="md">
            <Text fw={500} size="sm">Resources</Text>
            <Stack gap="xs">
              <Led value label="CPU Load" color="green" labelPosition="left" />
              <Led value label="Memory" color="yellow" labelPosition="left" />
              <Led
                value
                label="Disk Space"
                color="red"
                labelPosition="left"
                animate
                animationType="flash"
              />
            </Stack>
          </Stack>

          <Stack gap="md">
            <Text fw={500} size="sm">Security</Text>
            <Stack gap="xs">
              <Led value label="Firewall" color="green" labelPosition="left" />
              <Led value label="SSL Cert" color="green" labelPosition="left" />
              <Led value label="Auth Service" color="green" labelPosition="left" />
            </Stack>
          </Stack>
        </SimpleGrid>
      </Stack>
    </Paper>
  );
}

DEFCON Alert System

A fun example showing how to build a DEFCON (Defense Readiness Condition) alert system with animated LEDs:

Defense Readiness Condition

DEFCON 5

Normal readiness

DEFCON 4

Increased intelligence watch

DEFCON 3

Increase in force readiness

DEFCON 2

Further increase in force readiness

DEFCON 1

Maximum force readiness

import { useState } from 'react';
import { Button, Group, Paper, Stack, Text, Title } from '@mantine/core';
import { Led } from '@gfazioli/mantine-led';

const DEFCON_LEVELS = [
  { level: 5, color: 'blue', label: 'DEFCON 5', description: 'Normal readiness' },
  { level: 4, color: 'green', label: 'DEFCON 4', description: 'Increased intelligence watch' },
  { level: 3, color: 'yellow', label: 'DEFCON 3', description: 'Increase in force readiness' },
  { level: 2, color: 'orange', label: 'DEFCON 2', description: 'Further increase in force readiness' },
  { level: 1, color: 'red', label: 'DEFCON 1', description: 'Maximum force readiness' },
];

function Demo() {
  const [currentLevel, setCurrentLevel] = useState(5);

  return (
    <Paper p="xl" withBorder>
      <Stack gap="lg">
        <Title order={3} ta="center">Defense Readiness Condition</Title>
        
        <Stack gap="md">
          {DEFCON_LEVELS.map(({ level, color, label, description }) => (
            <Group key={level} justify="space-between">
              <Group gap="md">
                <Led
                  value={currentLevel === level}
                  color={color}
                  size="lg"
                  animate={currentLevel === level && level <= 2}
                  animationType={level === 1 ? 'flash' : 'pulse'}
                />
                <div>
                  <Text fw={currentLevel === level ? 700 : 400} size="sm">
                    {label}
                  </Text>
                  <Text size="xs" c="dimmed">
                    {description}
                  </Text>
                </div>
              </Group>
            </Group>
          ))}
        </Stack>

        <Group justify="center">
          <Button.Group>
            {[5, 4, 3, 2, 1].map((level) => (
              <Button
                key={level}
                onClick={() => setCurrentLevel(level)}
                variant={currentLevel === level ? 'filled' : 'default'}
                size="xs"
              >
                {level}
              </Button>
            ))}
          </Button.Group>
        </Group>
      </Stack>
    </Paper>
  );
}