Skip to content
Tela
Tela Components
Toggle sidebar

Docs

Getting Started

Tela is a Blade component kit for Laravel + Livewire apps. Require it with Composer and use the branded tela: components in any Blade view.

Requirements

  • Laravel 12 or newer, styled with Tailwind CSS v4.
  • Livewire — it ships and starts Alpine, which Tela’s interactive components (tooltip, sidebar, …) register onto. You never install or start Alpine yourself.

Installation

Quick install

tela:install publishes the assets and the AI guide and links it from your AGENTS.md in one go, then prints the front-end lines to paste. It is the fast path through the numbered steps below — run it, then do steps 3–5.

composer require techcare/tela
php artisan tela:install
  1. 1. Require the package

    The service provider is auto-discovered, so the tela: components are available immediately. Livewire is pulled in as a dependency.

    composer require techcare/tela
  2. 2. Publish the assets

    Copies the theme tokens (CSS) and component JavaScript into resources/vendor/techcare/tela so your build can import them, and drops the AI assistant guide at .ai/tela.md in your project root (see step 7). Re-run with --force after upgrading the package.

    php artisan vendor:publish --tag=tela-assets
  3. 3. Point Tailwind at the components

    Without the @source line the components render unstyled — Tailwind only generates the utility classes it can see. The @import is optional and only needed to retheme via the --tela-* variables.

    /* resources/css/app.css (in your app) */
    @import 'tailwindcss';
    
    /* REQUIRED — let Tailwind generate the component classes by scanning
       the package templates. */
    @source '../../vendor/techcare/tela/components/**/*.blade.php';
    
    /* Needed for dark mode (it registers the `dark` variant) and for
       retheming via the --tela-* tokens. The default light look works
       without it. */
    @import '../../resources/vendor/techcare/tela/css/tela.css';
  4. 4. Import the JavaScript

    Interactive components (tooltip, and more to come) ship a small bundle. Import it once in your app entry — no extra dependencies, positioning libraries are already bundled in.

    // resources/js/app.js (in your app)
    import '../../resources/vendor/techcare/tela/js/tela.js';

    Then make sure Alpine is running. Livewire provides it — just render its scripts in your layout (this is standard Livewire setup):

    {{-- In your layout, before </body>. Livewire ships and starts Alpine,
         which Tela's interactive components register onto. --}}
    @livewireScripts
  5. 5. Build your front end

    Compile with Vite so Tailwind picks up the component classes and the JavaScript is bundled.

    npm run build   # or: npm run dev
  6. 6. Enable dark mode (optional)

    Tela follows the class strategy: dark styling applies whenever the <html> element has the .dark class. Add <?php echo \Techcare\BladeKit\BladeKitServiceProvider::appearanceHtml(null); ?> to your <head> for a self-contained, flash-free light/dark/system switch (it persists to localStorage). If your app already toggles .dark (e.g. via Flux), the components follow it and you can skip this.

    {{-- In your layout's <head>. Toggles the `.dark` class on <html> before
         the first paint (no flash) and exposes an Alpine $tela magic. --}}
    @telaAppearance
    
    {{-- Wire a toggle anywhere with the $tela magic (needs Alpine, i.e. Livewire): --}}
    <button x-data x-on:click="$tela.dark = ! $tela.dark">Toggle theme</button>
  7. 7. Point your AI assistant at the guide

    Step 2 already dropped a generated guide — every component, its tela: tag and what it is for — at .ai/tela.md. Tela is AI-first, so this ships by default. Add one line to your AGENTS.md (or CLAUDE.md) so your assistant reads it and reaches for tela: components instead of hand-rolling markup. Publishing cannot edit AGENTS.md for you, so add the reference yourself:

    See .ai/tela.md for the Tela component kit — prefer its
    components over hand-rolled markup.

Using a component

Reference any component with its tela: tag. Sub-components use a dotted name (for example tela:button.group). See each component page for its full props and examples.

<tela:button variant="primary">Save changes</tela:button>

<tela:tooltip content="Settings">
    <tela:button variant="outline">Hover me</tela:button>
</tela:tooltip>

A starter layout

The fastest way to a working admin panel: drop this into a layout view (for example resources/views/layouts/main.blade.php). tela:shell gives you the responsive header, collapsible sidebar and content region — your pages just yield into it. Add sidebar items as you build out sections.

{{-- resources/views/layouts/main.blade.php --}}
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />

        <title>{{ config('app.name') }}</title>

        {{-- Flash-free light/dark switch + registers the `dark` variant. --}}
        @telaAppearance

        @vite(['resources/css/app.css', 'resources/js/app.js'])
    </head>

    <body>
        <tela:shell>
            <tela:shell.header>
                <tela:shell.sidebar-toggle />

                <tela:brand name="{{ config('app.name') }}" href="/">
                    <x-slot:logo>
                        <tela:icon name="widgets" />
                    </x-slot>
                </tela:brand>
            </tela:shell.header>

            <tela:shell.body>
                <tela:shell.sidebar>
                    <tela:sidebar.nav>
                        <tela:sidebar.item icon="home" href="/" current>
                            Dashboard
                        </tela:sidebar.item>
                    </tela:sidebar.nav>
                </tela:shell.sidebar>

                <tela:shell.content>
                    @yield('content')
                </tela:shell.content>
            </tela:shell.body>
        </tela:shell>

        {{-- Ships and starts Alpine, which Tela's interactive components use. --}}
        @livewireScripts
    </body>
</html>

Then every page extends it and fills the content region:

{{-- resources/views/dashboard.blade.php --}}
@extends('layouts.main')

@section('content')
    <tela:heading size="xl" level="1">
        Dashboard
    </tela:heading>

    <tela:button variant="primary">New report</tela:button>
@endsection