Search by

berlin-bird-studios / blade-components

jbolecke

This package provides a set of blade components

Package info

gitlab.berlin-bird.com/berlin-bird-studios/blade-components

pkg:composer/berlin-bird-studios/blade-components

Statistics

Installs: 1 832

Dependents: 0

Suggesters: 0


README

This package provides a set of reusable Blade components for Laravel applications. It simplifies the creation of UI elements and includes commands to generate listings and slide-over components with ease.

Table of Contents

Features

  • Predefined Blade components for common UI elements.
  • Commands to generate Livewire-based listings and slide-overs.
  • Customizable stubs for component generation.

Installation

Requirements: Livewire 3 or 4. Livewire 2 is no longer supported since version 1.1.0 (see CHANGELOG).

  1. Install the package via Composer:

     composer require berlin-bird-studios/blade-components
    
  2. Publish the configuration and/or views (only if you want to modify the configuration or override the default views):

     php artisan vendor:publish --tag=bbs-blade-components-config
     php artisan vendor:publish --tag=bbs-blade-components-views
    

Editor Image Upload

The package registers a POST route (default: /bbs-image-upload, name bbs.image.upload) that the bbs-input.editor.ck component uses for image uploads. The route is protected and validated by default.

Breaking change (1.1.0): Guests can no longer upload images, the route now requires a logged-in user and a valid CSRF token. If you published the config file, add the new keys below or remove them from your published file to use the defaults. Editor uploads on pages without login need a project-specific route.

  • Middleware: web (session + CSRF) and auth. The CK editor component already sends the CSRF token as ?_token=.
  • Ability: Optional. If editor_image_upload_ability is set (e.g. 'edit-text'), users without that Gate ability receive 403. By default any logged-in user can upload.
  • Rate limit: 30 uploads per minute per user.
  • Validation: Only jpg, jpeg, png, gif and webp images up to 10 MB, detected by file content, not by file name. SVG is not allowed, because SVG files can contain scripts. Files are stored under a random name. Invalid uploads receive 422 and nothing is stored.

All of this can be changed in the published config file:

KeyDefaultDescription
editor_image_upload_enabledtrueSet to false to not register the route. The CK editor needs a route with the configured name, so only disable it if you register your own.
editor_image_upload_middleware['web', 'auth']Middleware stack of the route. Keep web, otherwise there is no session and auth fails for everyone.
editor_image_upload_abilitynullGate ability the user needs, e.g. 'edit-text'. null allows every logged-in user.
editor_image_upload_rate_limit30Uploads per minute per user (or IP). null disables the limit.
editor_image_upload_max_size10240Maximum file size in kilobytes.
editor_image_upload_mimes['jpg', 'jpeg', 'png', 'gif', 'webp']Allowed image types.
editor_image_upload_pathnullDirectory on editor_image_disk to store the images in.

Note: If you registered your own upload route with the same URI in your project, it still overrides the package route.

Table of Components

Blade Components

bbs-analytics.matomo

  • Description: Embeds Matomo analytics tracking code.
  • Props:
    • siteId: The ID of the Matomo site (default: null).
    • url: The URL of the Matomo server (default: null).
  • Note: The values for siteId and url can either be passed as props or set via environment variables (MATOMO_URL, MATOMO_SITE_ID).
  • Example:
      <x-bbs-analytics.matomo siteId="1" url="https://matomo.example.com" />
    

bbs-slide-over

  • Description: A slide-over panel for displaying additional content.
  • Props:
    • title: The title of the slide-over.
    • subtitle: Subtitle text (default: null).
    • hideOnClickAway: Whether to close the slide-over when clicking outside (default: false).
    • footerButtons: Footer buttons content (default: false).
    • actionButtonText: Text for the action button (default: false).
    • actionButtonMethod: Method to call on action button click (default: false).
    • actionButtonParams: Parameters for the action button method (default: null).
    • closeButton: Custom close button content (default: null).
  • Example:
      <x-bbs-slide-over title="My Slide-Over" :hideOnClickAway="true">
      	<p>Content goes here.</p>
      </x-bbs-slide-over>
    

bbs-input

  • Description: A customizable input field.
  • Props:
    • type: The input type (default: text).
    • bgClasses: Background CSS classes (default: bg-transparent).
    • borderClasses: Border CSS classes (default: focus:border-gray-300 border-gray-300 focus:ring-gray-300).
  • Example:
      <x-bbs-input type="text" bgClasses="bg-white" borderClasses="border-blue-500" />
    

bbs-input.select

  • Description: A customizable select dropdown.
  • Props:
    • borderClasses: Border CSS classes (default: focus:ring-gray-300 focus:border-gray-300 border-gray-300).
  • Example:
      <x-bbs-input.select borderClasses="border-red-500">
      	<option value="1">Option 1</option>
      	<option value="2">Option 2</option>
      </x-bbs-input.select>
    

bbs-input.group

  • Description: A group wrapper for input fields with label and validation error support.
  • Props:
    • for: The for attribute for the label.
    • label: The label text (default: false).
    • shadow: Whether to apply shadow styling (default: true).
    • description: Description text (default: false).
    • errorFor: The field name for validation error messages (default: null).
  • Example:
      <x-bbs-input.group for="input-id" label="Input Label" description="This is a description.">
      	<x-bbs-input type="text" />
      </x-bbs-input.group>
    

bbs-input.validation-error

  • Description: Displays validation error messages for a specific field.
  • Props:
    • for: The field name for validation error messages.
  • Example:
      <x-bbs-input.validation-error for="input-id" />
    

bbs-input.button

  • Description: A customizable button component.
  • Props:
    • classes: CSS classes for the button (default: bg-blue-500 hover:bg-blue-200 ...).
  • Example:
      <x-bbs-input.button classes="bg-green-500 hover:bg-green-200"> Submit </x-bbs-input.button>
    

bbs-input.textarea

  • Description: A customizable textarea input field.
  • Props:
    • type: The input type (default: text).
    • bgClasses: Background CSS classes (default: bg-transparent).
    • borderClasses: Border CSS classes (default: focus:border-gray-300 border-gray-300 focus:ring-gray-300).
  • Example:
      <x-bbs-input.textarea bgClasses="bg-white" borderClasses="border-blue-500" />
    

bbs-input.checkbox

  • Description: A customizable checkbox input.
  • Props:
    • borderClasses: Border CSS classes (default: focus:ring-blue-500 border-gray-300).
    • textClasses: Text CSS classes (default: text-blue-300).
  • Example:
      <x-bbs-input.checkbox borderClasses="border-red-500" textClasses="text-green-500" />
    

bbs-input.editor.ck

  • Description: A CKEditor instance with extensive customization options.
  • Props:
    • loadFromCdn: Whether to load CKEditor from CDN (default: true).
    • fontSizes: Array of font sizes (default: [10, 12, 14, ...]).
    • transparent: Whether the editor background is transparent (default: true).
    • toolbarItems: Toolbar items for CKEditor (default: [heading, bold, italic, ...]).
    • allowedContent: Allowed HTML content (default: p h1 h2 strong em; ...).
    • language: Language for the editor (default: de).
    • placeholder: Placeholder text (default: Text).
    • colors: Array of color options (default: [black, red, white]).
    • hideToolbar: Whether to hide the toolbar (default: false).
    • fontFamilies: Array of font families (default: [Arial, Courier New, ...]).
    • defaultFontFamily: Default font family (default: Arial).
  • Note: Image uploads go to the package upload route, see Editor Image Upload.
  • Example:
      <x-bbs-input.editor.ck language="en" placeholder="Enter your text here" />
    

bbs-input.editor.trix

  • Description: A Trix editor with extensive customization options.
  • Props:
    • fileUploads: Whether to enable file uploads (default: false).
    • colors: An array of colors for text formatting (default: ['Schwarz' => 'rgb(0, 0, 0)', 'Weiß' => 'rgb(255, 255, 255)', 'Rot' => 'rgb(240, 15, 15)']).
    • transparent: Whether the editor background is transparent (default: true).
    • alignButtons: Whether to show alignment buttons (default: true).
    • hideToolbar: Whether to hide the toolbar (default: false).
    • hideBlockTools: Whether to hide block tools (default: true).
  • Example:
      <x-bbs-input.editor.trix :fileUploads="true" :transparent="false" :alignButtons="true" />
    

bbs-input.number

  • Description: A customizable number input field.
  • Props:
    • bgClasses: Background CSS classes (default: bg-transparent).
    • borderClasses: Border CSS classes (default: focus:border-gray-300 border-gray-300 focus:ring-gray-300).
  • Example:
      <x-bbs-input.number bgClasses="bg-white" borderClasses="border-blue-500" />
    

bbs-input.choices

  • Description: A customizable choices dropdown with advanced options.
  • Props:
    • name: The name of the input.
    • options: Array of options (default: []).
    • optionsVarName: Variable name for dynamic options (default: false).
    • position: Dropdown position (default: top).
    • tags: Whether to allow tags (default: false).
    • addItems: Whether to allow adding items (default: true).
    • renderChoiceLimit: Limit for rendering choices (default: -1).
    • editItems: Whether to allow editing items (default: false).
    • removeItems: Whether to allow removing items (default: true).
    • removeItemButton: Whether to show a remove button (default: true).
    • duplicateItemsAllowed: Whether duplicate items are allowed (default: false).
    • delimiter: Delimiter for separating items (default: null).
    • paste: Whether to allow pasting items (default: false).
    • resourceName: Resource name for dynamic options (default: false).
    • placeholderValue: Placeholder text (default: false).
    • allowHTML: Whether to allow HTML in options (default: true).
    • searchResultLimit: Limit for search results (default: 4).
    • maxItemCount: Maximum number of items (default: -1).
    • shouldSort: Whether to sort items (default: false).
    • tagColor: Color for tags (default: #3B82F6).
    • loadFromCdn: Whether to load Choices.js from CDN (default: true).
  • Example:
      <x-bbs-input.choices name="example" :tags="true" :addItems="true" />
    

bbs-input.datetime

  • Description: A customizable datetime picker.
  • Props:
    • enableTime: Whether to enable time selection (default: false).
    • enableSeconds: Whether to enable seconds selection (default: false).
    • monthSelectorStatic: Whether the month selector is static (default: false).
    • position: The position of the picker (default: bottom left).
    • mode: The mode of the picker (default: single).
    • hourIncrement: Hour increment step (default: 1).
    • minuteIncrement: Minute increment step (default: 5).
    • noCalendar: Whether to hide the calendar (default: false).
    • dateFormat: The format of the date (default: d.m.Y H:i).
    • allowInput: Whether to allow manual input (default: false).
    • defaultHour: Default hour value (default: 12).
    • hours24: Whether to use 24-hour format (default: true).
    • weekNumbers: Whether to show week numbers (default: false).
    • minDate: Minimum selectable date (default: false).
    • maxDate: Maximum selectable date (default: false).
    • disable: Whether to disable the picker (default: false).
    • color: The color for the picker (default: #3B82F6).
    • loadFromCdn: Whether to load Flatpickr from CDN (default: true).
    • wrapperClasses: CSS classes for the wrapper (default: false).
    • iconBoxClasses: CSS classes for the icon box (default: false).
    • inputClasses: CSS classes for the input (default: false).
    • placeholder: Placeholder text (default: false).
    • additionalOptions: Additional options for Flatpickr (default: []).
    • disableMobile: Whether to disable mobile mode (default: true).
    • theme: Theme for the picker (default: false).
  • Example:
      <x-bbs-input.datetime :enableTime="true" dateFormat="Y-m-d" />
    
  • Livewire updates: The picker also works when it is rendered by a Livewire update (a conditionally shown field, a modal that renders on selection). Each picker carries its own options, and a picker that finds no flatpickr on the page loads the flatpickr script and stylesheet itself. On a full page load they still come from the head and body stacks, so the layout needs @stack('head') and @stack('body') as before.
  • loadFromCdn="false": The page has to provide window.flatpickr itself (e.g. a <script> tag or window.flatpickr = flatpickr in your bundle). The stylesheet is still loaded from the CDN.
  • Published views: A published resources/views/vendor/blade-components/components/input/datetime.blade.php replaces this component completely and keeps the old behaviour. Delete it, or rebuild your changes on top of the current version (see CHANGELOG, 1.1.1).

bbs-input.image

  • Description: A customizable image input field.
  • Props:
    • id: The ID of the input (default: image).
    • model: The model binding for the input.
    • image: The image source.
  • Example:
      <x-bbs-input.image id="profile-image" model="user.image" image="/path/to/image.jpg" />
    

bbs-input.image-upload.filepond

  • Description: A file upload input using FilePond.
  • Props:
    • minFileSize: Minimum file size (default: null).
    • maxFileSize: Maximum file size (default: null).
    • maxTotalFileSize: Maximum total file size (default: null).
    • existingFilesVar: Variable for existing files (default: existing_files).
    • removeMethod: The method to remove files (default: removeFile).
  • Example:
      <x-bbs-input.image-upload.filepond :minFileSize="1024" :maxFileSize="1048576" />
    

bbs-typewriter

  • Description: A typewriter effect component.
  • Props:
    • strings: Array of strings to type (default: []).
    • typeSpeed: Typing speed in milliseconds (default: 60).
    • showCursor: Whether to show the cursor (default: true).
    • loop: Whether to loop the typing effect (default: false).
    • backDelay: Delay before typing the next string (default: 1000).
    • cursorChar: The character used as the cursor (default: |).
  • Example:
      <x-bbs-typewriter :strings="['Hello', 'World']" :typeSpeed="100" :loop="true" />
    

bbs-scroll-top

  • Description: A scroll-to-top button.
  • Props:
    • title: The title of the button (default: Ganz nach oben).
    • visibleFromScrollTo: The scroll position to show the button (default: 20).
    • additionalClasses: Additional CSS classes for the button (default: hover:bg-blue-500).
  • Example:
      <x-bbs-scroll-top title="Scroll Up" :visibleFromScrollTo="100" additionalClasses="bg-red-500" />
    

bbs-image-crop

  • Description: An image cropping component.
  • Props:
    • src: The source of the image.
    • viewMode: The view mode for the cropper (default: 3).
    • dragMode: The drag mode for the cropper (default: move).
    • aspectRatio: The aspect ratio for cropping (default: 16 / 9).
    • autoCropArea: The auto crop area (default: 1).
    • zoomable: Whether the image is zoomable (default: false).
  • Example:
      <x-bbs-image-crop src="/path/to/image.jpg" :aspectRatio="4 / 3" :zoomable="true" />
    

bbs-action-button.stack

  • Description: A stack of action buttons.
  • Props:
    • showIf: Whether to show the stack (default: false).
    • profileButtonText: Text for the profile button (default: Profil).
    • logoutButtonText: Text for the logout button (default: Abmelden).
    • bgClasses: Background CSS classes for the buttons (default: bg-blue-500).
    • profileButton: Custom profile button content (default: null).
    • hideProfileButton: Whether to hide the profile button (default: false).
  • Example:
      <x-bbs-action-button.stack :showIf="true" profileButtonText="My Profile" bgClasses="bg-green-500" />
    

bbs-tag-cloud

  • Description: A flexible, animated 3D tag cloud component using TagCanvas.js.

  • Props:

    • tags: The list of tags to display. Each tag must have a label.
    • width: Width of the canvas.
    • height: Height of the canvas.
    • depth: Depth effect for the 3D sphere.
    • freezeActive: Whether the animation freezes on hover.
    • clickToFront: Whether clicked tags rotate to the front.
    • textColor: Color of the tag texts.
    • outlineColour: Color of the tag outlines.
    • outlineThickness: Thickness of the tag outlines.
    • initialSpeed: Initial rotation speed.
    • minSpeed: Minimum rotation speed.
    • maxSpeed: Maximum rotation speed.
    • shape: Shape of the tag cloud (sphere, vcylinder, hcylinder).
    • withLinks: Whether tags are clickable links or just text.
    • linkRoute: The route name for tag links (if withLinks is true).
    • linkParamField: The field on the tag object to pass to the route.
    • anchorAttr: Additional attributes for the a tag.
  • Example:

      <x-bbs-tag-cloud
      	:tags="$tags"
      	textColor="#3399cc"
      	:clickToFront="false"
      	:withLinks="true"
      	linkRoute="route.name"
      	linkParamField="item_id"
      	class="absolute inset-0"
      />
    

    ### bbs-toast

    • Description: Stackable toast notifications powered by Alpine.js. Listens for a window event (default: notify) and renders contextual messages (info, success, warning, danger, message).
    • Props:
    • eventName (string, default: notify) — Custom event name to listen for.
    • displayDuration (int, default: 8000) — Duration (ms) before auto-dismiss.
    • soundEffect (bool, default: false) — Play a sound on show.
    • max (int, default: 20) — Max number of toasts kept in the stack.
    • position (string, default: bottom-right) — One of: top-right, bottom-right, top-left, bottom-left.
    • soundUrl (string, default: BBS ding.mp3) — URL to audio file.

    • Events / Payload:

    • Dispatch a window event with the payload:

        window.dispatchEvent(
        	new CustomEvent('notify', {
        		detail: {
        			variant: 'success', // 'info' | 'success' | 'warning' | 'danger' | 'message'
        			title: 'Saved!',
        			message: 'Your changes have been stored.',
        			sender: { name: 'Jane', avatar: 'https://example.com/jane.jpg' }, // optional, used by 'message' variant
        		},
        	}),
        );
      
    • Example (layout):

      {{-- Place once in your app layout --}}
      <x-bbs-toast-notification
      	eventName="notify"
      	:displayDuration="6000"
      	:soundEffect="true"
      	:max="10"
      	position="bottom-right"
      />
    
    • Example (trigger from Alpine/Blade):
      <button
      	type="button"
      	x-on:click="$dispatch('notify', {
              variant: 'success',
              title: 'Saved',
              message: 'All changes persisted.'
          })"
      	class="btn btn-primary"
      >
      	Notify
      </button>
    
    • Livewire Helper Trait (recommended)::
    • Create a small helper trait to trigger notifications from Livewire/PHP:app/Traits/WithNotifications.php
              <?php
    
          namespace App\Traits;
    
          trait WithNotifications
          {
              private function notify(string $variant, string $title, string $message): void
              {
                  $this->js(<<<JS
                      window.dispatchEvent(new CustomEvent('notify', {
                          detail: {
                              variant: '{$variant}',
                              title: '{$title}',
                              message: '{$message}'
                          }
                      }))
                  JS);
              }
          }
      ```html
    

Commands

make:listing

  • Description: Generates a new listing component.
  • Usage:
      php artisan make:listing {name} {component-name?} {slide-over-name?} {--permission=} {--force} {--inline} {--test} {--stub=} {--namespace=listings} {--prefix=}
    
  • Options:
    • name: The name of the listing.
    • component-name: The Blade component name for the listing.
    • slide-over-name: The corresponding slide-over name.
    • --permission: Permissions for the listing.
    • --namespace: Namespace for the component (default: listings).

make:slide-over

  • Description: Creates a new slide-over component.
  • Usage:
      php artisan make:slide-over {name} {--button-text=} {--hide-on-click-away} {--title=} {--force} {--inline} {--test} {--stub=} {--namespace=slide-overs} {--prefix=}
    
  • Options:
    • name: The name of the slide-over.
    • --button-text: Text for the button to open the slide-over.
    • --hide-on-click-away: Whether to close the slide-over when clicking outside.
    • --title: Title of the slide-over.

Customization

You can customize the stubs used for generating components by modifying the files in the stubs/ directory. The InteractsWithLivewireStubs trait handles the replacement of placeholders in these stubs.

Development

php artisan test --parallel   # or: vendor/bin/phpunit

testbench.yaml and workbench/ contain a small Livewire app for checking components in a browser (vendor/bin/testbench serve, then open /datetime). tests/Browser/datetime-picker.mjs drives it with Playwright and checks the datetime picker after Livewire updates:

npm install
npx playwright install chromium
npm run test:browser

License

This package is open-sourced software licensed under the MIT license.