kupce's avatar
Level 3

Organising Custom UI Components

What is the recommended approach to maintain custom built UI components and be able to show available UI components to the designer to build/ improve a page upon those available resources?

What are your approaches ?

Currently all features/component I construct from top of my head, non visual. I just find them in the app. ( Non scalable )

I am thinking of building a visual representation UI Library.

The website initially was built on HTML. Then a coder converted to Laravel. I took over and built upon it with my best understand as a Non Laravel developer. Soon realising without this visual library it get inconsistent design elements.

Each component is built on HTML using Bootstrap 4.

Essentially I want to build a brand guidelines along with UI Library so I can pass it to a coder / designer and they understand what we already have. Any suggestions?

0 likes
8 replies
LaryAI's avatar
Level 58

Certainly! Your instinct to create a visual UI Library and capture brand guidelines is spot on. This is a tried and trusted best practice, especially as a project grows and more people (coders or designers) get involved.

Here's a practical solution that works well for Laravel (or any web project), with some code examples for illustration.


1. Centralize your UI Components

First, identify your UI components and make them reusable. In Laravel with Blade, these are ideally stored as Blade Components.

For example, instead of repeating button code, create:

resources/views/components/button.blade.php
<button type="{{ $type ?? 'button' }}" class="btn btn-{{ $variant ?? 'primary' }}">
    {{ $slot }}
</button>

Use it like:

<x-button variant="success">Save</x-button>

2. Create a "Storybook" or UI Library Page

Make a dedicated route/page that showcases every component—like a Storybook for your team. This lets everyone see what's available and what it looks like.

Example:

Create a simple UI library route:

routes/web.php
Route::view('/ui-library', 'ui-library')->name('ui-library');

Then in resources/views/ui-library.blade.php:

@extends('layouts.app')

@section('content')
    <h1>UI Components Library</h1>
    
    <h2>Buttons</h2>
    <x-button variant="primary">Primary</x-button>
    <x-button variant="secondary">Secondary</x-button>
    <x-button variant="success">Success</x-button>

    <h2>Alerts</h2>
    <x-alert type="success" message="Success alert!" />
    <x-alert type="danger" message="Danger alert!" />

    <!-- Add more components as you build them -->
@endsection

3. Document Usage and Brand Guidelines

You can document:

  • How and when to use each component
  • Design principles (colors, logo use, spacing, etc.)

Either document directly in the ui-library.blade.php, or split into a Markdown/Notion/Readme document.

For example, add notes in your Blade:

<h2>Buttons</h2>
<p>
    Use primary buttons for main actions.<br>
    <x-button variant="primary">Primary</x-button>
</p>

4. Show to Designers/Developers

When a new designer/coder joins, simply point them to /ui-library and (optionally) your documentation. They'll instantly see and understand your design system.


5. Automate and Maintain

  • Whenever you build a new component, update the UI Library page.
  • Optionally, use tools like Storybook (if you use Vue or React), or just plain Blade like above for Laravel.

6. Example Project Structure

resources/views/components/
    button.blade.php
    alert.blade.php
resources/views/
    ui-library.blade.php

Summary

  • Use Blade Components for UI pieces
  • Showcase them on a /ui-library page
  • Document usage and guidelines (inline in your UI Library, or in a README/Notion/Markdown)
  • Maintain as you grow

With this structure, your designers and developers will always know what's available, how it looks, and how to use it—avoiding inconsistent design and wasted time rebuilding the same things.


Extra:
If you'd like to do this with plain HTML (no Laravel-specific features), the process is similar: Create a HTML page that includes and documents all your UI pieces.

Let me know if you want a sample project or more detailed code!

JussiMannisto's avatar

A general-purpose visual library might be difficult to implement. A dropdown menu is very different from a button, dashboard sidebar, or accordion. You could create a demo page, but it would have to be manually crafted based on what you want to showcase.

I'd probably just write UI design guidelines and include information about available components with visual examples.

P.S. Bootstrap 4 is quite old by now. I recommend migrating to version 5 at some point. Migration was pretty easy from what I remember: mostly just new features and some renamed classes.

1 like
martinbean's avatar

@kupce What components are we talking about? If Blade components, then I’d just create a “kitchen sink” page that lists each component, and then the options available for those components.

kupce's avatar
Level 3

We have numerous Blade Components e.g. Someone built a local Dashboard example.

I needed help so hired someone. Now I am not convince that the current attempt is the right direction/approach.

Each Blade component loads via iframe.

kupce's avatar
Level 3

Here is an example of component blade loaded via <iframe>

Here is the actual code for the blade

@props([
    'mainTitle' => 'Ready to Convert Your Garage?',
    'subtitle' => 'Get a quote from a local garage contractor.',
    'buttonText' => 'Get a Quote',
    'trust' => 'Licensed and Insured Specialist'
])

<div class="container cta-wrapper d-flex justify-content-center">
    <div class="cta-container position-relative">
        <div class="position-absolute cta-quote cta-quote-left">
            <x-icon-quote-left />
        </div>
        <div class="position-absolute cta-quote cta-quote-right">
            <x-icon-quote-right />
        </div>
        
        
        <div class="cta-inner text-center d-flex flex-column align-items-center">
            <h2 class="cta-main-title">{{ $mainTitle }}</h2>
            <p class="cta-subtitle">{{ $subtitle }}</p>
            
            <div class="cta-actions d-flex flex-column align-items-center">
                <a rel="nofollow" class="btn btn-border" href="#" data-toggle="modal" data-target="#enquireModal">{{ $buttonText ?? 'Get a Quote' }}</a>
                <p class="cta-trust">{{ $trust ?? 'Trusted by 100+ London homeowners.' }}</p>
            </div>
        </div>
    </div>
</div>

And here is a code that loads the iframe ( The coder might have used AI to generate this not sure )

JussiMannisto's avatar

Why iframes? Why not render the components normally in the same document, so you don't have to do all that messy cross-window communication just to get the height right.

Speaking of which, this is pretty bad:

setTimeout(sendHeight, 10);
setTimeout(sendHeight, 50);
setTimeout(sendHeight, 100);
setTimeout(sendHeight, 200);

I'm guessing they resorted to hacks like this because they used the wrong observer and were getting poor results. They needed ResizeObserver, not MutationObserver.

1 like
kupce's avatar
Level 3

Looks like I need to find a different coder. Someone who can build a better version.

Please or to participate in this conversation.